2

まず、CUDA を使用しているアプリケーションについて説明する必要があります。

これはかなり標準的な熱流シミュレーションです。float の 3D 配列 (変更可能な温度と熱、一定の k 値、sar_value、その他いくつか) を取得し、それらを GPU に割り当てられた線形配列にコピーします。これらはすべてグローバル メモリにあります。

次に、熱流を計算するカーネル関数を起動します。このカーネルを、2 次元のブロック構造と 1D のスレッド構造で起動します。ブロックは、熱流計算を実行しているシミュレーション キューブの x 座標と y 座標に対応します。スレッドは z 座標に対応します。パフォーマンスを最大化するために、すべてのスレッド/ブロック座標は、合計キューブ サイズの倍数です。

次に、各セルで長い計算を実行します。すべての配列は線形であるため、z、y、x 方向の次のセルを計算するためにオフセットを準備しました。空間的局所性の大部分は書き込み/読み取りメモリで発生するため、テクスチャ メモリはオプションではありません。計算ごとに、合計で、大きな配列への 2 回の書き込み、6 回の定数の大きな配列の読み取り (300 MB の float 配列の 1 つのインデックスのように)、8 つの変更可能な大きな配列の読み取り、6 回の定数の小さな配列の読み取り (300 の立方根のように) があります。 MB)。これらはすべて 2 行のコードで行われます。同じメモリ位置の複数の読み取りは、キャッシュされていると想定しているため、個別の読み取りとして含めませんでした。

次に、この計算で得た結果について説明します。

Tesla C1060 で約 2 億 2500 万セル/秒を取得します。大規模なデータ セット (4000 ~ 6000 万セル) では、特定のポイントまで、セルごとに 1 スレッド、2 セルごとに 1 スレッド、4 セルごとに 1 スレッドを起動しても、パフォーマンスに違いは見られません。これは、計算の制限要因が実際のメモリフェッチであることを示しています。複数のブロックに対して 1 つのスレッドを起動すると、システムのメモリの過負荷が軽減されるため、各計算は高速になりますが、計算の並列性は低くなります (パフォーマンスは向上しませんが、+ または - 1 または 2 パーセント)。

私は何を試しましたか?最も空間的にローカルな定数の大きな配列を 3D テクスチャ メモリに入れようとしましたが、3 倍から 4 倍の悲惨な速度低下が発生しました。データ アクセス パターンは、大きな配列内の各インデックスが 1 回または 2 回しかアクセスされないようなものであり、さらに、コンパイル時に入力のサイズを必ずしも把握しているとは限らないため、定数メモリは実行可能ではないと判断しました。大きな定数配列で 1D テクスチャを試しました。も悪い。

他にできることはありますか?また、1 秒あたりのフェッチ バイト数 (2 億 2500 万/秒 * 100 バイト程度) を見ることができれば、Tesla C1060 のメモリ帯域幅のほぼ 10 の倍数に十分収まります。なぜメモリが制限要因なのですか? 誰かが同様の熱流計算のためにデータセットを「タイル張り」したことをどこかで見ました (「Mint」の背後にいる人々による論文にあると思います)、これはどういう意味ですか?

回答ありがとうございます。ご不明な点はコメント欄よりお気軽にお尋ねください。

4

1 に答える 1

3

次に、各セルで長い計算を実行します。すべての配列は線形であるため、z、y、x 方向の次のセルを計算するためにオフセットを準備しました。

ワープ内の配列で取得するアクセス パターンのタイプを慎重に検討してください。ワープ内のスレッドは、「行優先」の順序で連続したアドレスにアクセスする必要があります。たまたま「列優先」のようなアクセス パターンになった場合、コードは必要以上に多くのメモリ トランザクションを発行することになります。

CUDA プログラミング ガイド 4.2 のセクション 2.2、スレッド階層では、スレッド インデックスがスレッド ID にどのようにマップされるかが説明されています。連続するスレッド ID が (少なくとも大部分は) 連続する配列インデックスにもつながることを確認してください。

于 2012-06-13T03:11:34.753 に答える