【问题标题】:CUDA Overlap Data is not workingCUDA 重叠数据不起作用
【发布时间】:2013-03-31 08:19:46
【问题描述】:

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

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

我的系统在下面

  • 操作系统:Window 7 64bit
  • CUDA:版本 5.0.7
  • 开发套件:Visual studion 2008
  • GPU:GTX 680

我得到一个个人资料视图是这样的

我没有重叠,代码如下:

    -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]));

    }

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

【问题讨论】:

  • 更多注意您在 Stack Overflow 问题中使用的格式和语言。当您发布它时,它几乎是一团难以理解的混乱。

标签: cuda overlapping cuda-streams


【解决方案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() 传输它们。

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      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),因为已验证适用于 Windows 的 nvidia 驱动程序存在问题!当您使用板载 gpu 时,所说的驱动程序没有完全加载,因此避免了很多错误。此外,在工作时保持系统响应能力!

      1. 确保您的并发问题与旧驱动程序(包括 BIOS 版本)、错误代码、无法使用的设备等其他问题无关。
      2. 转到计算机>属性
      3. 选择左侧的高级系统设置
      4. 转到“高级”选项卡
      5. 关于性能点击设置
      6. 在“视觉效果”选项卡中,选择“调整以获得最佳性能”项目符号。

      这将禁用航空和几乎所有视觉效果。如果此配置有效,您可以尝试逐一启用视觉效果框,直到找到导致问题的精确框!

      或者,您可以:

      1. 桌面右键,选择个性化
      2. 从基本主题中选择一个不包含 aero 的主题。

      这也可以像上面那样工作,但启用了更多的视觉选项。对于我的两台设备,这个设置也有效,所以我保留了它。

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

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

      更新:问题已通过新的 Windows 安装完全解决!!之前的步骤改善了某些情况下的行为,但全新安装解决了所有问题!

      我会尝试找到一种不太激进的方法来解决这个问题,也许只恢复注册表就足够了。

      【讨论】:

        猜你喜欢
        • 2011-08-29
        • 1970-01-01
        • 1970-01-01
        • 2021-12-25
        • 1970-01-01
        • 2022-01-21
        • 1970-01-01
        • 1970-01-01
        • 2017-09-11
        相关资源
        最近更新 更多