1

ブロックごとのデータ配列があります。cudaグリッド内にN個のブロックと、サイズNのデータ「block_data []」の定数配列があります。

したがって、特定のブロック 'X' 内のすべてのスレッドは、block_data[X] に 1 回だけアクセスし、その値で何かを行います。

私の質問は次のとおりです。このブロードキャスト方式は効率的に機能しますか? そうでない場合、どのようなアプローチをとるべきですか?

コメントの後に編集: 定数メモリに関する私の唯一の問題は、64K を超えるブロックを持つ可能性があるため、サイズが限られていることです。それは64KB以上を意味します

よろしく

4

2 に答える 2

2

通常のグローバルメモリアクセスを使用するだけの場合、トランザクションはかなり非効率的ですが、カーネルが実行している作業の量にもよりますが、影響はおそらく非常に小さいものです。

sizeof(block_data)は1バイトだと思います(あなたの質問から推測されます「... 64Kブロック以上になる可能性があります。それは64KB以上を意味します」)。

  • 操作がL1にキャッシュされている場合は、必要な1ビットの情報に対して128バイトをフェッチします(sizeof(block_data))。ブロック内の他のワープが同じデータを要求する場合は、L1から取得する必要があります。負荷の効率は1/128ですが、ブロックに対して1回だけ支払う必要があります。
  • 操作がL1にキャッシュされていない場合(たとえば、「-dlcm = cg」をアセンブラーに渡す場合)、32バイトをフェッチします。効率は1/32ですが、ワープごとに1回支払います。
  • データがロードされると、ワープ内のすべてのスレッドにブロードキャストされます。

const __restrict__別の方法は、データがa)読み取り専用であり、b)他のポインターによってエイリアスされていないことをコンパイラーに示すようにデータをマークすることです。コンパイラーはアクセスが均一であることを検出できるため、読み取り専用キャッシュの1つを使用するようにアクセスを最適化できます(たとえば、定数キャッシュ、またはコンピューティング機能> = 3.5の場合、読み取り専用データキャッシュ、別名テクスチャキャッシュ)。

于 2012-09-11T14:03:52.097 に答える
1

配列の値を変更する場合はblock_data[N]、共有メモリの概念を使用することをお勧めします__shared__。の値を変更しない場合は、キャッシュの概念をblock_data[N]使用するか使用してください。__const__L2 キャッシュを使用すると、1536KB のメモリ (Kepler) を取得できます。

于 2012-09-10T19:39:07.637 に答える