CUDA重叠数据不起作用

时间:2013-03-31 08:19:46

标签: cuda overlapping cuda-streams

使用ste来重叠数据传输与内核执行在我的系统中不起作用。

您好 我想在CUDA中使用重叠计算和数据传输,但我不能。 NVIDIA帮助文档说如果您使用流,则可以进行重叠计算和数据传输。 但我的系统没有工作 请帮帮我。

我的系统在

之下
  • OS:Window 7 64bit
  • CUDA:ver 5.0.7
  • Develp kit:Visual studion 2008
  • GPU:GTX 680

我收到个人资料视图就像这样enter image description here

我没有重叠,代码如下:

    -new pinned memory 
        cudaHostAlloc((void **)&apBuffer, sizeof(BYTE)*lBufferSize,cudaHostAllocDefault);
    -call function

   //Input Data
    for(int i=0;i<m_n3DChannelCnt*m_nBucket;++i)
    {
        cudaErrorChk_Return(cudaMemcpyAsync(d_ppbImg[i],ppbImg[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyHostToDevice,m_pStream[i/m_nBucket]));
    }
   //Call Function
    for(int i=0;i<m_n3DChannelCnt ;++i)
    {KernelGetVis8uObjPhsPhs<<<nBlockCnt,nThreadCnt,0,m_pStream[i]>>>(d_ppbVis[i],d_ppbAvg[i],d_ppfPhs[i],d_ppfObj[i],d_ppbAmp[i]
                                            ,nTotalSize,d_ppstRefData[i],d_ppbImg[i*m_nBucket],d_ppbImg[i*m_nBucket+1],d_ppbImg[i*m_nBucket+2],d_ppbImg[i*m_nBucket+3]
                                            ,fSclFloatVis2ByteVis);

    }
   //OutputData
    for(int i=0;i<m_n3DChannelCnt;++i)
    {
        if(ppbVis && ppbVis[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbVis[i],d_ppbVis[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
        if(ppbAvg && ppbAvg[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAvg[i],d_ppbAvg[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
        if(ppfPhs && ppfPhs[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfPhs[i],d_ppfPhs[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
        if(ppfObj && ppfObj[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfObj[i],d_ppfObj[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
        if(ppbAmp && ppbAmp[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAmp[i],d_ppbAmp[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));

    }

请告诉我为什么分析器不会显示内核执行和数据传输的重叠。

3 个答案:

答案 0 :(得分:1)

您需要以正确的顺序调用cudaMemcpyAsync()和内核启动。在计算能力3.5之前,只有一个队列用于调用设备端操作,并且它们不会被重新排序。将“调用函数”和“输出数据”阶段组合到类似

的阶段
//Call Function and OutputData
for(int i=0;i<m_n3DChannelCnt ;++i)
{KernelGetVis8uObjPhsPhs<<<nBlockCnt,nThreadCnt,0,m_pStream[i]>>>(d_ppbVis[i],d_ppbAvg[i],d_ppfPhs[i],d_ppfObj[i],d_ppbAmp[i]
                                        ,nTotalSize,d_ppstRefData[i],d_ppbImg[i*m_nBucket],d_ppbImg[i*m_nBucket+1],d_ppbImg[i*m_nBucket+2],d_ppbImg[i*m_nBucket+3]
                                        ,fSclFloatVis2ByteVis);

    if(ppbVis && ppbVis[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbVis[i],d_ppbVis[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
    if(ppbAvg && ppbAvg[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAvg[i],d_ppbAvg[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
    if(ppfPhs && ppfPhs[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfPhs[i],d_ppfPhs[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
    if(ppfObj && ppfObj[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfObj[i],d_ppfObj[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));
    if(ppbAmp && ppbAmp[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAmp[i],d_ppbAmp[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i]));

}

您只能将内核启动与第一个或最后一个内存副本重叠,因为您在流中有五个cudaMemcpyAsync()调用,这些调用再次无法重新排序。在内存中连续分配所有五个数组,以便您可以使用单个cudaMemcpyAsync()传输它们。

总的来说,我注意到数据传输所需的时间比内核运行的时间长,因此重叠的计算和复制只能为您的情况提供较小的加速。

答案 1 :(得分:0)

您可能想要检查代码是否在LINUX中按预期工作(即重叠)。我刚刚遇到了同样的问题,发现WINDOWS可能有一些问题(无论是在NVIDIA的驱动程序还是Windows本身),这会干扰CUDA流中的重叠。

您可以尝试检查SDK中的“simpleStreams”示例是否与您机器中的重叠一起使用。对于我的情况,在Windows上运行的“simpleStream”根本没有重叠,但它在Linux中运行完美。具体来说,我在Fermi GTX570上使用CUDA 5.0 + VS2010。

答案 2 :(得分:-1)

  

TL; DR:问题是由Nsight Monitor中的WDDM TDR延迟选项引起的!设置为false时,会出现问题。相反,如果你设置了   TDR延迟值为非常高的数字,并且“启用”选项为   是的,问题就消失了。

请阅读下面的其他(较旧)步骤,直到我找到上述解决方案,以及其他一些可能的原因。

我最近才能解决这个问题!它特定于Windows和 aero 我认为。请尝试这些步骤并发布结果以帮助其他人!我在GTX 650和GT 640上尝试过它。

  

在您执行任何操作之前,请考虑using both onboard gpu(as display) and the discrete gpu (for computations),因为nvidia驱动程序已经验证了Windows的问题!当你使用板载gpu时,说驱动程序没有满载,所以很多bug都被规避了。此外,在工作时保持系统响应能力!

  1. 确保您的并发问题与旧驱动程序(包括BIOS版本),错误代码,无法使用的设备等其他问题无关。
  2. 转到计算机&gt;属性
  3. 选择左侧的高级系统设置
  4. 转到“高级”标签
  5. 关于效果点击设置
  6. 在“视觉效果”选项卡中,选择“调整以获得最佳性能”项目符号。
  7. 这将禁用空气动力学和几乎所有视觉效果。如果此配置有效,您可以尝试逐个启用视觉效果框,直到找到导致问题的精确框!

      

    或者,您可以:

    1. 右键单击桌面,选择个性化
    2. 从基本主题中选择一个没有空气动力学的主题。
    3. 这也可以如上所述,但启用了更多可视化选项。对于我的两个设备,此设置也有效,所以我保留了它。

        

      当您尝试这些解决方案时,请回到此处并发布您的发现!

      对我来说, 解决了大多数情况下的问题(我做过的平铺dgemm) ,但请注意我仍然无法正常运行“simpleStreams”实现并发......

        

      更新 <问题通过新的Windows安装完全解决 !!前面的步骤改进了某些情况下的行为,但是全新安装解决了所有问题!

      我会尝试找一种解决这个问题的不那么激进的方法,也许只需恢复注册表即可。