从cuda cpu function - gpu kernel overlap开始,我知道如何同时执行gpu和cpu函数。但是另一种情况是,gpu和cpu函数必须串行执行,问题是当cpu被gpu内核执行阻塞时,cpu进程会挂起吗?如果是的话,cpu的占用率应该很低,对吗?
下面是我的cuda代码,很简单,只是为了测试
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
__global__ void kernel(float *d_data)
{
//dead loop
while(1)
{
*d_data = -1;
*d_data = 1/(*d_data);
*d_data = (*d_data) / (*d_data);
}
}
int main()
{
float *d_data;
cudaMalloc(&d_data, sizeof(float));
kernel << <1, 1 >> >(d_data);
//cpu process would be blocking here
float data;
cudaMemcpy(&data, d_data, sizeof(int), cudaMemcpyDeviceToHost);
printf("%f\n",data);
return 0;
}
使用top
检查cpu的占用率是100%
%Cpu10 : 75.1 us, 24.9 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
我确认我启动的cpu进程正在Cpu10上运行。
我错过了什么吗?我非常感谢你的帮助!
答案 0 :(得分:2)
CPU进程(实际上是线程)不会挂起。
内核调用之后的cudaMemcpy
操作被发送到同一个cuda流(default stream),因此它阻塞(CPU线程)并等待内核完成。
cudaMemcpy
调用中的块是(默认情况下)CPU旋转等待,而不是线程收益。
理论上,you can modify the CUDA device synchronization behavior。但是,您需要尝试使用标志来查看是否有任何选项可以为您提供比默认行为更优惠的内容。
如果您知道内核将执行多长时间,您还可以在CPU代码中使用类似sleep()
的函数来生成特定时间段的线程,然后使用{{3}之类的机制确定是继续还是继续等待。