在我的旧 GeForce 8800GT 上使用 CUDA 中的内存时,我总是有一个奇怪的 0.04 毫秒开销。我需要将 ~1-2K 转移到我设备的常量内存中,处理其上的数据并从设备中仅获取一个浮点值。
我有一个使用 GPU 计算的典型代码:
//allocate all the needed memory: pinned, device global
for(int i = 0; i < 1000; i++)
{
//Do some heavy cpu logic (~0.005 ms long)
cudaMemcpyToSymbolAsync(const_dev_mem, pinned_host_mem, mem_size, 0, cudaMemcpyHostToDevice);
my_kernel<<<128, 128>>>(output);
//several other calls of different kernels
cudaMemcpy((void*)&host_output, output, sizeof(FLOAT_T), cudaMemcpyDeviceToHost);
// Do some logic with returned value
}
我决定用这段代码测量 GPU 内存的工作速度(注释所有内核调用,添加cudaDeviceSynchronize
调用):
//allocate all the needed memory: pinned, device global
for(int i = 0; i < 1000; i++)
{
//Do some heavy cpu logic (~0.001 ms long)
cudaMemcpyToSymbolAsync(const_dev_mem, pinned_host_mem, mem_size, 0, cudaMemcpyHostToDevice);
cudaMemcpyAsync((void*)&host_output, output, sizeof(FLOAT_T), cudaMemcpyDeviceToHost);
cudaDeviceSynchronize();
// Do some logic with returned value
}
我测量了循环的执行时间,得到了约 0.05 秒(因此,每次迭代 0.05 毫秒)。奇怪的是,当我尝试做更多的内存工作(添加额外的 cudaMemcpyToSymbolAsync 和 cudaMemcpyAsync 调用)时,每次调用我得到额外的 <0.01 ms 时间。对应这家伙的研究:http ://www.cs.virginia.edu/~mwb7w/cuda_support/memory_transfer_overhead.html
他还获得了每次将 1K 块传输到 GPU 的 0.01 毫秒。那么这 0.04 毫秒(0.05 - 0.01)的开销是从哪里来的呢?有任何想法吗?可能我应该在新卡上尝试此代码吗?
在我看来,在 cudaDeviceSynchronize 和 CPU 代码之后,我的 GeForce 进入了某种省电模式或类似的模式。