CUDA プログラミング入門 (1): イメージ操作を使用してスレッドの構成とカーネル関数の使用法を確認する
「超並列プロセッサ プログラミングの実践」の学習。他の章ではCUDA Cのコラムに焦点を当てています。
初めて CUDA C プログラミングに触れるときに直接読むことはお勧めしません。
- 第 3 章 CUDA の概要 - CUDA C プログラミング ベクトルの追加
- 第4章 CUDAデータ並列実行モデル
- 第5章 CUDAメモリ
- 第 6 章 CUDA パフォーマンスの最適化 (原書へのリンク付き)
この記事を理解すると、畳み込みの最適化について学ぶことができます: CUDA 畳み込みの計算とその最適化 - 1 次元の畳み込みを例にします
1. スレッドブロックの構成
2 次元画像処理を例として、スレッドの構成とカーネル関数呼び出しの使用法を明確にします。
ここで、あるピクチャ(行列)の値を演算する必要があるのですが、ピクチャのサイズが ImgSize=ImgHeight ImgWidth であるとすると、処理には ImgSize スレッドが必要になります。
2 次元のスレッド ブロックが使用される場合、スレッド ブロックのデータ構造は となりdim3 Block(BLOCK_SIZE,BLOCK_SIZE)
、スレッド ブロック内のスレッドの数が BLOCK_SIZE BLOCK_SIZE および BLOCK_SIZE=16 であることを示します。dim3 Block(x,y,z)
これは dim3 データ構造のパラメータであり、このとき、x=y=16、z のデフォルトは 1 であるため、下図に示すように、
複数のスレッド ブロックで構成されるスレッド グリッドをこの図にマッピングできます。スレッド ブロックの水平列は x で、ImgWidth に対応します。垂直行は y で、ImgHeight に対応します。z 次元がある場合は、対応することができます。したがって、ImgWidth*ImgHeight のサイズのグラフの場合
、必要なスレッド ブロックの数は [ImgWidth/BLOCK_SIZE] (切り上げ、つまり (ImgWidth - 1 + BLOCK_SIZE)/BLOCK_SIZE)、[ImgHeight/BLOCK_SIZE]、z 次元も 1 です。次にdim3 Grid((ImgWidth - 1 + BLOCK_SIZE)/BLOCK_SIZE, (ImgHeight- 1 + BLOCK_SIZE)/BLOCK_SIZE))
、前と同様に、dim3 のデータ構造は (x, y, z) の形式になります。
これで、グリッドとスレッドブロックのデータ構造が利用可能になります。
2. カーネル関数の呼び出し
画像のアドレスは でfloat* pin
、出力アドレスは で、float* out
その関数を__global__ void PicKernel(float* pin, float* pout, int width, int height);
呼び出します
PicKernel <<< Grid, Block >>> (pin, pout, ImgWidth, ImgHeight)
。まだ理解していない場合は、この段落をさらに読んでください。
3. カーネル関数の作成
カーネル関数では、スレッドを P_in および P_out で処理されたデータにマップする必要があります。
4. プログラムを完了する
完全なプログラムでは、p_in を処理するために main 関数でカーネル関数を呼び出す必要があります。通話の前後には、メモリの割り当てと回復、およびデータのコピーも必要です。
メモリの割り当てと回復、データのコピーも必要です。