4

VS 2010 用の Parallel Nsight 2.1 エディションを使用して、CUDA プログラムを最適化しようとしています。

私のプログラムは、GTX 480 ボードを搭載した Windows 7 (32 ビット) マシンで実行されます。CUDA 4.1 32 ビット ツールキットと 301.32 ドライバーをインストールしました。

プログラムの 1 サイクルは、デバイスへのホスト データのコピー、カーネルの実行、およびデバイスからホストへの結果のコピーで構成されます。

以下のプロファイラー結果の図でわかるように、カーネルは 4 つの異なるストリームで実行されます。各ストリームのカーネルは、「ストリーム 2」でデバイスにコピーされたデータに依存しています。そのため、異なるストリームでカーネルを起動する前に、asyncMemcpy が CPU と同期されます。

ここに画像の説明を入力

この図で私がいらいらするのは、最初のカーネル起動の終わり (10.5778679285) とカーネル実行の始まり (10.5781500) の間に大きなギャップがあることです。カーネルの起動には約 300 us かかります。これは、1 ミリ秒未満の処理サイクルで膨大なオーバーヘッドです。

さらに、カーネルの実行とホストへの結果のデータ コピーのオーバーラップがないため、オーバーヘッドがさらに増加し​​ます。

この動作に明らかな理由はありますか?

4

1 に答える 1

6

トレースからわかる問題は 3 つあります。

  1. Nsight CUDA 分析は、API 呼び出しごとに約 1 マイクロ秒追加します。CUDA ランタイムと CUDA ドライバー API トレースの両方が有効になっています。CUDA ランタイム トレースを無効にすると、幅を 50 µs 減らすことができると思います。

  2. Windows 7 で GTX 480 を使用しているため、WDDM ドライバー モデルで実行しています。WDDM では、ドライバーは作業を送信するためにカーネル呼び出しを行う必要があり、多くのオーバーヘッドが発生します。このオーバーヘッドを削減するために、CUDA ドライバーは要求を内部 SW キューにバッファーし、キューがいっぱいになると要求をドライバーに送信し、同期呼び出しによってフラッシュされます。cudaEventQuery を使用してドライバーに強制的に作業をフラッシュさせることは可能ですが、これはパフォーマンスに他の影響を与える可能性があります。

  3. 深さ優先の方法で作品をストリームに送信しているようです。コンピューティング機能 2.x および 3.0 デバイスでは、幅優先でストリームに送信すると、より良い結果が得られます。あなたの場合、カーネル間にオーバーラップが見られる場合があります。

タイムラインのスクリーンショットからは、すべてのカーネルの完了後にメモリ コピーが開始される理由を判断するのに十分な情報が得られません。API 呼び出しパターン I を考えると、各ストリームの起動が完了した後に開始される転送を確認できるはずです。

すべてのストリームが完了するのを待っている場合は、cudaStreamSynchronize を 4 回呼び出すよりも cudaDeviceSynchronize を実行する方が速い可能性があります。

Nsight の次のバージョンには、SW キューイングと、コンピューティング エンジンおよびメモリ コピー エンジンへの作業の送信を理解するのに役立つ追加機能が含まれます。

于 2012-08-30T16:15:05.193 に答える