为什么CUDA内存复制速度会像这样,一些不变的驱动程序开销?

时间:2012-10-29 23:08:01

标签: memory cuda overhead

在我的旧GeForce 8800GT上使用CUDA中的内存时,总是有0.04毫秒的奇怪开销。我需要将~1KK传输到我的设备的恒定内存,在其上处理该数据并从设备获得一个浮点值。

我有一个使用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 ms。 那么0.04毫秒(0.05 - 0.01)的开销是从哪里来的?有任何想法吗?可能是我应该在新卡上试用这段代码?

在我看来,在cudaDeviceSynchronize和CPU代码之后,我的GeForce进入了一些省电模式或类似的东西。

1 个答案:

答案 0 :(得分:1)

我建议你增加你正在实现的线程数

    //Use malloc() to allocate memory on CPU. 
    //Change mem_size to the total memory to be tranferred to GPU.        
    cudaMemcpyToSymbolAsync(const_dev_mem, pinned_host_mem, mem_size, 0, cudaMemcpyHostToDevice);
    dim3 dimBlock(128,2);
    dim3 dimGrid(64000,1);
    my_kernel<<<dimGrid, dimBlock>>>(output);
    //several other calls of different kernels
    //change size field to 1000*sizeof(FLOAT_T)
    cudaMemcpy((void*)&host_output, output, sizeof(FLOAT_T), cudaMemcpyDeviceToHost);
    // Do some logic with returned value 

如果代码崩溃(因为更多线程或更多GPU内存),请使用循环。但是,减少它们。