私は現在、グローバル メモリ帯域幅によって制限される HLSL シェーダーに取り組んでいます。各メモリ トランザクションで、できるだけ多くのメモリを結合する必要があります。CUDA および OpenCL に関する NVIDIA のガイドライン (DirectCompute のドキュメントはかなり不足しています) に基づくと、コンピューティング機能 2.0 の最大メモリ トランザクション サイズは 128 バイトで、アクセス可能な最大ワードは 16 バイトです。グローバル メモリ アクセスは、ワープ内のスレッドによってアクセスされるデータが同じ 128 バイト セグメントに分類される場合に結合できます。これを念頭に置いて、構造が 16 バイトを超える場合、構造化バッファはメモリの合体に悪影響を及ぼしませんか?
2 つの float4 の構造があるとします。それらを A および B と呼びます。非発散ワープで発行された命令の 1 つのメモリ トランザクションで、A または B のいずれかにアクセスできますが、両方にはアクセスできません。メモリのレイアウトは ABABABAB のようになります。連続する構造体を共有メモリに読み込もうとしている場合、この方法でデータを格納することでメモリ帯域幅が浪費されませんか? たとえば、アクセスできるのは A 要素のみですが、ハードウェアはメモリ トランザクションを結合するため、128 バイトの連続データ (半分は B 要素) を読み取ります。基本的に、メモリ帯域幅の半分を無駄にしています。構造体のバッファではなく、バッファの構造体である AAAABBBB のようなデータを格納する方がよいのではないでしょうか? それとも、これは L1 キャッシュによって処理されますか? 次の命令が B 要素を読み込むときに高速にアクセスできるように、B 要素はどこにキャッシュされますか? 他の唯一の解決策は、偶数番号のスレッドが A 要素にアクセスし、奇数番号の要素が B 要素にアクセスすることです。
メモリ帯域幅が実際に浪費されている場合、利便性以外で構造化バッファを使用する理由がわかりません。誰かが理解できるように、これを十分に説明したことを願っています。NVIDIA 開発者フォーラムでこれを尋ねますが、まだダウンしていると思います。NVIDIA Nsight フレーム プロファイラーを実行しようとすると、Visual Studio がクラッシュし続けるため、データの保存方法の変更によってメモリ帯域幅がどのように影響を受けるかを確認するのが困難です。PS、NVIDIA Nsight フレーム プロファイラーを正常に実行できた人はいますか?