0

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

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

我的系统在下面

  • 操作系统:Window 7 64bit
  • CUDA:版本 5.0.7
  • 开发套件:Visual Studion 2008
  • 显卡: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]));

    }

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

4

3 回答 3

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().

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

于 2013-03-31T13:17:54.337 回答
0

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

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

于 2013-05-28T02:16:14.833 回答
-2

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

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

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

在您执行任何操作之前,请考虑同时使用板载 gpu(作为显示器)和离散 gpu(用于计算),因为已验证适用于 windows 的 nvidia 驱动程序存在问题!当您使用板载 gpu 时,所说的驱动程序没有完全加载,因此避免了很多错误。此外,在工作时保持系统响应能力!

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

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

或者,您可以:

  1. 右键桌面,选择个性化
  2. 从没有航空的基本主题中选择一个主题。

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

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

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

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

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

于 2015-03-18T08:28:46.703 回答