私はCUDAとOpenCLのプログラミングガイドを読んでいますが、銀行の競合とは何なのかわかりません。彼らは、問題自体を詳しく説明することなく、問題を解決する方法に少しだけ飛び込みます。誰も私がそれを理解するのを助けることができますか?ヘルプがCUDA/OpenCLのコンテキストにあるのか、一般的なコンピューターサイエンスの銀行の競合にあるのか、私は好みがありません。
Nvidia(およびそれに関するAMD)gpusの場合、ローカルメモリはメモリバンクに分割されます。各バンクは一度に1つのデータセットしかアドレスできないため、ハーフワープが同じバンクからデータをロード/ストアしようとすると、アクセスをシリアル化する必要があります(これはバンクの競合です)。 gt200 gpusの場合、16バンク(fermiの場合は32バンク)、AMD gpusの場合は16または32バンク(57xx以上:32、すべて以下:16))、32ビットの粒度でインターリーブされます(バイト0-3はバンク1、バンク2の4〜7、...、バンク1の64〜69など)。より良い視覚化のために、基本的に次のようになります。
Bank | 1 | 2 | 3 |...
Address | 0 1 2 3 | 4 5 6 7 | 8 9 10 11 |...
Address | 64 65 66 67 | 68 69 70 71 | 72 73 74 75 |...
...
したがって、ハーフワープの各スレッドが連続する32ビット値にアクセスする場合、バンクの競合はありません。このルールの例外(すべてのスレッドが自身のバンクにアクセスする必要があります)はブロードキャストです:すべてのスレッドが同じアドレスにアクセスする場合、値は一度だけ読み取られ、すべてのスレッドにブロードキャストされます(GT200の場合、ハーフワープのすべてのスレッドがアクセスする必要があります)同じアドレス、iirc fermiとAMD gpusは、同じ値にアクセスする任意の数のスレッドに対してこれを行うことができます)。
並行してアクセスできる共有メモリは、モジュール(バンクとも呼ばれます)に分割されます。同じバンクに2つのメモリ位置(アドレス)が存在する場合、bank conflictが発生し、その間にアクセスがシリアルに行われ、パラレルアクセスの利点が失われます。
簡単に言えば、バンクの競合は、メモリアクセスパターンがメモリシステムで利用可能なバンク間でIOを配布できない場合です。次の例で概念を詳しく説明します。
整数の2次元512x512配列があり、DRAMまたはメモリシステムに512バンクがあるとします。デフォルトでは、配列データは、arr [0] [0]がバンク0に、arr [0] [1]がバンク1に、arr [0] [2]がバンク2に…というようにレイアウトされます。 arr [0] [511]はバンク511に移動します。arr[x] [y]を一般化するには、バンク番号yを占有します。これで、いくつかのコード(下図を参照)が列メジャー方式でデータにアクセスし始めます。 yを一定に保ちながらxを変更すると、最終的な結果は、すべての連続したメモリアクセスが同じバンクにヒットすることになるため、バンクの競合が発生します。
int arr[512][512];
for ( j = 0; j < 512; j++ ) // outer loop
for ( i = 0; i < 512; i++ ) // inner loop
arr[i][j] = 2 * arr[i][j]; // column major processing
通常、このような問題は、配列をバッファリングするか、配列内の要素の素数を使用することにより、コンパイラーによって回避されます。
(CUDA Bank Conflict)これが役立つことを願っています。これは非常に良い説明です...
http://en.wikipedia.org/wiki/Memory_bank
and http://mprc.pku.cn/mentors/training/ISCAreading/1989/p380-weiss/p380-weiss.pdf
このページから、メモリバンクの詳細を確認できます。しかし、@ Grizzlyの発言とは少し異なります。このページでは、銀行は次のようになっています
銀行1 2 3
アドレス| 0、3、6 ... | | 1、4、7 ... | | 2、5、8 ... |
これが役立つことを願って