0

私のシステムでは、ストリームを使用してデータ転送とカーネル実行をオーバーラップさせることができません。

こんにちは、CUDA で重複計算とデータ転送を使用したいのですが、できません。NVIDIA のヘルプ ドキュメントには、ストリームを使用すると、計算とデータ転送のオーバーラップが可能であると記載されています。しかし、システムが機能していません。助けてください。

私のシステムは以下です

  • OS:Windows7 64bit
  • CUDA : バージョン 5.0.7
  • 開発キット : Visual studion 2008
  • GPU:GTX680

プロフィールを取得 View is Like thisここに画像の説明を入力

オーバーラップしていません。コードは以下のとおりです。

    -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 より前は、デバイス側の操作を呼び出すためのキューが 1 つしかなく、並べ替えられませんでした。「Call Function」フェーズと「OutputData」フェーズを次のように結合します

//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()ただし、ストリーム内に 5 つの呼び出しがあり、これも並べ替えられないため、カーネルの起動をメモリ コピーの最初または最後にオーバーラップさせることしかできません。5 つの配列すべてをメモリ内で連続して割り当てて、単一の で転送できるようにしますcudaMemcpyAsync()

ただし、全体的には、データ転送はカーネルの実行よりもはるかに長い時間がかかることに気付きました。そのため、計算とコピーを重複させても、この場合はわずかな速度向上しか得られません。

于 2013-03-31T13:17:54.337 に答える
0

コードが LINUX で期待どおりに (つまり、オーバーラップして) 機能するかどうかを確認したい場合があります。同じ問題が発生したばかりで、CUDA ストリーミングのオーバーラップを妨げる WINDOWS に (NVIDIA のドライバーまたは Windows 自体に) いくつかの問題がある可能性があることがわかりました。

SDK の「simpleStreams」の例がマシンでオーバーラップして動作するかどうかを試して確認できます。私の場合、Windows で動作する「simpleStream」はまったく重複していませんが、Linux では完全に動作します。具体的には、Fermi GTX570 で CUDA 5.0 + VS2010 を使用しています。

于 2013-05-28T02:16:14.833 に答える
-2

TL;DR:この問題は、Nsight モニタの WDDM TDR 遅延オプションが原因です! false に設定すると、問題が発生します。代わりに、TDR 遅延値を非常に高い数値に設定し、「有効」オプションを true に設定すると、問題は解消されます。

上記の解決策にたどり着くまでの他の(古い)手順と、その他の考えられる原因については、以下をお読みください。

私は最近、この問題をほとんど解決することができました! それは窓とエアロに固有のものだと思います。これらの手順を試して、結果を投稿して他の人を助けてください! GTX 650 と GT 640 で試しました。

何かを行う前に、オンボード gpu (ディスプレイとして) とディスクリート gpu (計算用) の両方を使用することを検討してください。これは、Windows 用の nvidia ドライバーで問題が確認されているためです。オンボード GPU を使用すると、ドライバーが完全にロードされないため、多くのバグが回避されます。また、作業中もシステムの応答性を維持!

  1. 並行性の問題が、古いドライバー (BIOS バージョンを含む)、間違ったコード、機能しないデバイスなどの他の問題に関連していないことを確認してください。
  2. コンピューター>プロパティに移動します
  3. 左側で高度なシステム設定を選択します
  4. 詳細タブに移動します
  5. オン パフォーマンス クリック設定
  6. [視覚効果] タブで、[最適なパフォーマンスに調整する] を選択します。

これにより、エアロとほぼすべての視覚効果が無効になります。この構成が機能する場合は、問題を引き起こしている正確なボックスが見つかるまで、視覚効果用のボックスを 1 つずつ有効にしてみてください。

または、次のこともできます。

  1. デスクトップを右クリックし、パーソナライズを選択します
  2. 基本テーマの中からエアロのないテーマを選びます。

これも上記と同じように機能しますが、より多くの視覚オプションが有効になっています。私の 2 つのデバイスでは、この設定も機能するので、そのままにしておきます。

これらの解決策を試すときは、ここに戻って結果を投稿してください。

私にとっては、ほとんどの場合(私が作成したタイル張りのdgemm)の問題を解決しましたが、まだ「simpleStreams」を適切に実行して同時実行を達成できないことに注意してください...

更新:この問題は、新しい Windows インストールで完全に解決されました!! 前の手順で一部のケースの動作が改善されましたが、新規インストールですべての問題が解決しました!

この問題を解決するための根本的ではない方法を見つけようとします。レジストリだけを復元するだけで十分かもしれません。

于 2015-03-18T08:28:46.703 に答える