- 追加された行はこの色です。
- 削除された行はこの色です。
- シェアードメモリ へ行く。
シェアードメモリについて
-----
#contents
-----
*シェアードメモリとは [#qa0c288c]
シェアードメモリ(shared memory)はブロック内のスレッドが共用して使えるオンチップメモリで,
グローバルメモリに比べて非常に高速です.シェアードメモリはバンクと呼ばれるメモリモジュールに分割されており,
スレッド間のバンク・コンフリクトがなければレジスタアクセスと同じ速さで処理できます.
*確保方法 [#l98926d2]
シェアードメモリ変数,配列はCUDAカーネル上で宣言します.~
静的な確保(コンパイル時に配列の長さが決まる)の場合,
#code(C){{
__shared__ float x[16];
}}
動的な確保(実行時に配列の長さが決まる)の場合は,カーネル呼び出し側で <<< ... >>> の第3引数で指定します.
#code(C){{
__global__
void KernelFunc()
{
extern __shared__ float x[];
// 処理
...
}
__host__
void HostFunc(int shared_size)
{
...
KernelFunc<<< grid, block, sizeof(float)*shared_size >>>();
...
}
}}
*シェアードメモリの大きさ [#b9a1ae3b]
デバイスプロパティを取得し,sharedMemPerBlockで確認できます.
#code(C){{
cudaDeviceProp dev;
cutilSafeCall(cudaGetDeviceProperties(&dev, 0));
printf(" shared memory / block : %d (KB)\n", dev.sharedMemPerBlock/1024);
}}
*バンク・コンフリクト(Programing guide 5.1.2.5節参照) [#r13909d4]
広いメモリバンド幅を達成するためにシェアードメモリはバンクと呼ばれるサイズが同じメモリモジュールに分割されています.
これらのバンクは同時並列にアクセスすることができ,例えば,
n回のメモリアクセス場所が全て異なるバンクであり,これらが同時にリード or ライトされた場合,
単一メモリモジュールの場合と比べてn倍広いバンド幅となります.
しかし,もしもリクエストしたメモリアドレスが同じバンク上にあった場合,
バンク・コンフリクトが発生し,そのアクセスは直列に実行されます.