【CUDA】シェアードメモリの使用方法

CUDA入門
マウスコンピューター/G-Tune

GPUのメモリの種類で、シェアードメモリ(SharedMemory/共有メモリ)というものがあります。

シェアードメモリは、グローバルメモリと比べて非常に高速なので、繰り返しグローバルメモリにアクセスする必要があるときは、シェアードメモリをいったん介したほうが高速化できる可能性があります。

最適化をするなら必須の要素なので、ぜひ使い方を覚えましょう。

シェアードメモリの特徴

・同じブロック内のスレッドどうしなら値を共有できる。
・グローバルメモリにアクセスするより数十倍高速。
・1ブロックごとに48~64KBまで確保できる。

テスト処理内容

・ 8000×8000のunsigned char型 二次元配列で、ある要素を中心として、その周辺3×3と5×5の平均値を求める。
・結果を別の二次元配列に保存する。
・この処理を全要素に行う。

コード例

3×3 平均 シェアード無し

カーネル呼び出し部

カーネル

3×3 平均 シェアード有り

カーネル呼び出し部

カーネル

5×5のコードは、単純に3×3の平均範囲を増やしたもので、長くなってしまうので省略しています。

速度比較

各カーネルの時間は以下の通りです。

3×3平均5×5平均
シェアードメモリ使用無し2.5msec5.7msec
シェアードメモリ使用有り 2.9msec4.5msec

5×5でグローバルメモリへのアクセス回数が増えてくると、シェアードメモリを使用したほうが早くなることが判ります。

補足

占有率

シェアードメモリを確保しすぎると、占有率(Occupancy)が下がる可能性があります。

占有率とはWarp(32Threadが1Warp)の最大数と同時実行可能なWarp数の比です。
共有資源を確保しすぎていると、同時実行可能なWarp数は減ります。

高ければ良いわけではありませんが、10・20%など、極端に低い場合はシェアードメモリの使用容量か利用自体を見直したほうが良いでしょう。

占有率はNsightのタイムラインから見ることができます。

シェアードメモリの有効性

以前よりもグローバルメモリへのアクセス速度が上がってきているため、シェアードメモリとの速度差が減ってきています。

シェアードメモリの容量は以前からほとんど増えていない上に、NVIDIAの方のいわく、シェアードメモリを使用しなくても高速にできるようにする方針だそうです。

シェアードメモリを使うとカーネルが複雑化するので、使わないで済むようになってほしいですね。

マウスコンピューター/G-Tune