当内核启动时,cuda会以某种方式阻止并将所有分配的托管内存传输到GPU吗?我刚和uma玩过,结果很奇怪。至少在我看来。
我创建了2个数组并向内核发送A,B内核调用未触及但无法访问。当我触摸B时程序崩溃。
0 0 0 here1
如果我注释掉b[0] = 1;
行代码运行正常:
0 0 0 here1 after1 0 here2 1 after2
为什么会这样?
__global__ void kernel(int* t)
{
t[0]++;
}
int main()
{
int* a;
int* b;
std::cout << cudaMallocManaged(&a,sizeof(int)*100) << std::endl;
std::cout << cudaMallocManaged(&b,sizeof(int)*100) << std::endl;
std::cout << b[0] << std::endl;
kernel<<<1,1,0,0>>>(a);
std::cout << "here1" << std::endl;
b[0] = 1;
std::cout << "after1" << std::endl;
cudaDeviceSynchronize();
std::cout << b[0] << std::endl;
std::cout << "here2" << std::endl;
std::cout << a[0] << std::endl;
std::cout << "after2" << std::endl;
return 0;
}
答案 0 :(得分:2)
cuda是否以某种方式阻止并传输所有已分配的托管内存 内核启动时的GPU?
是的,前提是您的设备的计算能力低于6.0。
在这些设备上,托管内存的工作原理是在内核启动之前将所有托管内存复制到GPU,并在同步时将所有托管内存复制回主机。在该时间跨度内,从主机will lead to a segmentation fault访问托管内存。
您可以通过attaching it to a stream using cudaStreamAttachMemAsync()
更具体地了解要为给定内核复制的内存,并将内核启动到该流中。