私が作成したアルゴリズムを、Tesla T10 プロセッサ (計算能力 1.3) から Tesla M2075 (計算能力 2.0) に切り替えようとしています。切り替え中に、アルゴリズムの速度が低下していることに驚きました。分析したところ、新しいマシンで cuda ストリームがブロックされていることが原因であることがわかりました。私のアルゴリズムには、分割して並行して実行できる 3 つの主要なタスクがあります。メモリの再編成 (CPU で実行可能)、ホストからデバイスへのメモリのコピー、およびデバイスでのカーネルの実行です。ストリームを分割する古いマシンでは、3 つのタスクを次のようにオーバーラップさせることができました (すべて NVidia Visual Profiler のスクリーンショット)。
ただし、新しいマシンでは、前のカーネルの実行が完了するまで、CPU 計算を開始する前にストリームがブロックされます。
一番上の行を見るとわかるように、すべてのオレンジ色のブロックは cudaStreamSynchronize 呼び出しであり、カーネルが完全に異なるストリーム上にある場合でも、前のカーネルの実行が完了するまでブロックされます。ストリームを介した最初の実行では機能し、正しく並列化されるようですが、その後問題が発生するため、何かをブロックしている可能性があると考え、ストリームの数を増やしてみた結果、次の結果が得られました。
ここでは、何らかの理由で最初の 4 つのストリームのみがブロックされていることがわかります。その後、適切に並列化が開始されます。最後の試みとして、最初の 4 つのストリームを 1 回だけ使用してから、後のストリームを使用するように切り替えることでハックしようとしましたが、それでも機能せず、4 つのストリームごとに停止し、他のストリームを同時に実行させました。 :
そのため、この問題の原因と診断方法についてのアイデアを探しています。私は自分のコードを詳しく調べましたが、間違っている可能性はありますが、そこにバグがあるとは思いません。各ストリームは独自のクラスにカプセル化されており、そのクラスのメンバーである単一の cudaStream_t への参照しか持たないため、別のストリームを参照してブロックする方法がわかりません。
バージョン 1.3 と 2.0 の間で、ストリームの動作方法に、私が気付いていない変更点はありますか? 共有メモリが解放されず、それを待たなければならないものでしょうか? この問題を診断する方法についてのアイデアは大歓迎です。