我正在阅读桑德斯的“CUDA示例”一书,其中作者提到p.441:例如,当我们在光线跟踪器中启动内核时,GPU开始执行我们的代码,但CPU继续执行GPU完成之前我们程序的下一行。 - 突出显示2014年3月4日
我想知道这个陈述是否正确。例如,如果下一条指令CPU继续执行,取决于GPU内核输出的变量怎么办?它会导致错误吗?根据我的经验,它不会导致错误。那么作者究竟是什么意思呢?
非常感谢!
答案 0 :(得分:2)
是的,作者是对的。假设我的内核启动如下:
int *h_in_data, *d_in_data, *h_out_data, *d_out_data;
// code to allocate host and device pointers, and initialize host data
...
// copy host data to device
cudaMemcpy(d_in_data, h_in_data, size_of_data, cudaMemcpyHostToDevice);
mykernel<<<grid, block>>>(d_in_data, d_out_data);
// some other host code happens here
// at this point, h_out_data does not point to valid data
...
cudaMemcpy(h_out_data, d_out_data, size_of_data, cudaMemcpyDeviceToHost);
//h_out_data now points to valid data
内核启动后,CPU立即继续执行主机代码。但是设备生成的数据(d_out_data
或h_out_data
)尚未就绪。如果主机代码试图使用h_out_data
指向的任何内容,那么它将只是垃圾数据。此数据仅在第二次cudaMemcpy
操作后生效。
请注意,在第二个h_out_data
之前使用数据(cudaMemcpy
)不会产生错误,如果你的意思是分段错误或其他一些运行时错误。但任何产生的结果都不正确。
答案 1 :(得分:2)
CUDA中的内核启动默认是异步的,即控件将在启动后返回CPU。现在,如果CPU的下一条指令是另一个内核启动,那么您不必担心,只有在先前启动的内核完成执行后才会启动此启动。 但是,如果下一条指令只是访问内核结果的某些CPU指令,则可能存在访问垃圾值的问题。因此,必须过度小心,并且应该在需要时进行设备同步。