CUDAの基礎,メモ

1. CUDAとは

  • 統合開発環境
  • GPUコンピューティング向け
  • NVIDIAのGeForceシリーズのGPUが搭載されている必要あり

2. キーワード

2.1 スレッド(Thread)

  • 実行単位
  • 基本、それぞれのスレッドが非同期で動く

    2.2 ブロック(Block)

  • スレッドをまとめたもの
  • 合計512スレッドまで
  • スレッドの組み合わせは3次元表現まで可能(512,16*16,8*8*8)

    2.3 グリッド(Grid)

  • ブロックをまとめたもの
  • 合計65,535ブロックまで
  • ブロックの組み合わせは2次元で表現

グリッド、ブロック、スレッドの関係

2.4 カーネル(Kernel)

  • GPU側に実行させるプログラムのこと
  • このプログラムを書くことをカーネルプログラミングと言う
  • カーネルプログラミングをする際、独自の変数と予約語がある

2.4.1 threadIdx.〇〇

  • thread index の略?
  • カーネルが動作しているスレッドのインデックス番号
  • 要は何番目のスレッドかわかる
  • スレッドは3次元表現までありえるので、threadIdx.x,y,zが存在

2.5 ワープ(Warp)

  • スレッドの方では、結局32スレッドずつ動く
  • 32スレッド = 1ワープ
  • よって、スレッドの処理の区切りは32ずつだと良い感じ
  • メモリ共有はワープ単位でのみ

3. ここまでのまとめ

  • ブロックあたりの最大スレッド数 = 512
  • グリッドあたりの最大ブロック数 = 65,535
  • ワープあたりのスレッド数 = 32

4. 同期処理(__synchthreads()関数)

  • 同ブロック内のスレッド全てがこの関数に到達するまで一時停止する
  • 異なるブロックでは同期はされない

5. ホスト(__host__)とデバイス(__device__)

  • CPU = ホスト
  • GPU = デバイス

5.1 __global__

  • デバイス側
  • 返り値は常にvoid型
  • 再帰は不可能
  • <<<>>>を使用した実行時の指定が可能
  • static変数はもてない
  • __global__で指定した関数へのポインタは利用可能
  • __host__と同時には無理
  • デバイス側での処理が終わる前に呼び出し側に処理が戻る
  • シェアードメモリを利用して、256byteまでのデータを渡すことが可能

5.2 __device__

  • 再帰は不可能
  • static変数はもてない
  • 可変長引数はもてない
  • __device__で指定した関数ポインタは利用できない

5.3 __host__

  • ホスト側でのみ呼び出せる
  • ホスト側の通常の関数
  • __global__と同時に使用不可
  • __device__と同時に使用可能
  • __device__と同時に使用し、ホスト側とデバイス側の両方から呼び出せる関数を作成可能
  • __host__, __device__, __global__のどれも選択肢ないとデフォルトは__host__を選択したことになる

6. 関数

6.1 krnlVecAdd<<<A, B, C, D>>>

  • A : dim3型, グリッドの中にあるブロックのサイズ
  • B : dim3型, ブロックの中にあるスレッドのサイズ
  • C : size_t型, ブロック当たり割り当てるシェアードメモリの容量を、バイト単位で指定(省略可)
  • D : ストリームの番号(省略可)
1
2
3
dim3 grid_dimension(8, 8);
dim3 block_dimension(16, 16, 16);
krnlVecAdd<<<grid_dimension, block_dimension>>>(A, B, C);
  • グリッドの中に8*8のブロックがある
  • ブロックの中に161616のスレッドがある