ブロックとスレッドのいくつかの値について経験的にテストしましたが、特定の値を使用すると実行時間を大幅に短縮できます。
ブロックとスレッドの違いがわかりません。ブロック内のスレッドに特定のキャッシュメモリがある可能性があると思いますが、私にとってはかなりあいまいです。今のところ、ブロック/スレッドに割り当てられているN個の部分で関数を並列化します。
私の目標は、使用するメモリのサイズに関して、ブロック数とスレッド数を自動的に調整することです。それは可能でしょうか?ありがとうございました。
ブロックとスレッドのいくつかの値について経験的にテストしましたが、特定の値を使用すると実行時間を大幅に短縮できます。
ブロックとスレッドの違いがわかりません。ブロック内のスレッドに特定のキャッシュメモリがある可能性があると思いますが、私にとってはかなりあいまいです。今のところ、ブロック/スレッドに割り当てられているN個の部分で関数を並列化します。
私の目標は、使用するメモリのサイズに関して、ブロック数とスレッド数を自動的に調整することです。それは可能でしょうか?ありがとうございました。
ブロックと糸のサイズを自動的に調整することは非常に難しい問題だと思います。簡単であれば、CUDAにはおそらくこの機能があります。
その理由は、最適な構成は実装と実装しているアルゴリズムの種類に依存するためです。最高のパフォーマンスを得るには、プロファイリングと実験が必要です。
考慮できるいくつかの制限があります。
カーネルに使用法を登録します。現在の実装の占有率。
注:スレッドの数を増やしても、最高のパフォーマンスが得られるとは限りません。最高のパフォーマンスは、アプリケーションで適切な占有率を取得し、GPUコアを常にビジー状態に保つことによって得られます。
これまでのところ、HongZhouの答えは良いです。詳細は次のとおりです。
共有メモリを使用する場合は、最初に検討することをお勧めします。これは、リソースが非常に限られており、並列処理を制御する多くの変数を制約する非常に特殊なニーズがカーネルにある可能性が低いためです。大きな領域を共有するスレッドが多いブロックか、小さな領域を共有するスレッドが少ないブロックがあります(一定の占有率の下で)。
コードがマルチプロセッサあたりわずか16KBの共有メモリで動作できる場合は、より大きな(48KB)L1キャッシュ呼び出しを選択することをお勧めします。
cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
-Xptxas=-dlcm=cg
さらに、カーネルがグローバルメモリに注意深くアクセスする際の汚染を回避するために、コンパイラオプションを使用して非ローカルグローバルアクセスに対してL1キャッシュを無効にすることができます。
占有率に基づく最適なパフォーマンスについて心配する前に、CUDA> = 4.1でデバイスのデバッグサポートがオフになっていることを確認することもできます(または適切な最適化オプションが提供されている場合は、このスレッドの私の投稿を読んで適切なコンパイラ構成を確認してください)。
これでメモリ構成ができ、レジスタが実際に積極的に使用されるようになったので、さまざまな占有率でのパフォーマンスを分析できます。
占有率(マルチプロセッサごとのワープ)が高いほど、マルチプロセッサが(メモリトランザクションまたはデータ依存関係のために)待機する可能性は低くなりますが、同じL1キャッシュ、共有メモリ領域、およびレジスタファイルを共有するスレッドが多くなります(CUDA最適化ガイドおよびこのプレゼンテーション)。
ABIは、可変数のレジスターのコードを生成できます(詳細については、引用したスレッドを参照してください)。ただし、ある時点でレジスタのスピルが発生します。つまり、レジスタ値は一時的に(比較的低速のオフチップの)ローカルメモリスタックに格納されます。
起動境界とパラメーターを変更しながら、プロファイラーでストールの理由、メモリ統計、および算術スループットを監視すると、適切な構成を見つけるのに役立ちます。
理論的には、アプリケーション内から最適な値を見つけることは可能ですが、クライアントコードをさまざまなデバイスと起動パラメーターの両方に最適に調整することは簡単ではなく、すべてのターゲットデバイスアーキテクチャにカーネルの再コンパイルまたはさまざまなバリアントをデプロイする必要があります。
私はここで非常に良い答えを持っています。つまり、これはブロックとスレッドの最適な分布を計算するのが難しい問題です。