CUDAでカーネル関数内全スレッド同期

目次

CUDA Advent Calendar 2019 17日目の記事です.

Cooperative groups

CUDAではカーネル関数外でstreamの同期を行うcudaStreamSynchronizeやデバイス全体で同期を行うcudaDeviceSynchronize,カーネル関数内で同期を行う__syncthreadsなど,様々な同期関数が用意されています.
CUDA 9ではこれらの同期関数に加えより柔軟に同期を行えるための機能としてCooperative Groupsというものを提供しています.
これを使うと制約はありますが全スレッド同期などが可能となります.

全スレッド同期

全スレッド同期を行うサンプルコードがこちら. 実行するとcooperative groupsで全スレッド同期した方は常に連番が出力され,同期していない方はWarp間で同期が行われないために実行毎にいろいろな並び順になると思います.
カーネル関数を立ち上げるときはいつもの<<<>>>ではなく,cudaLaunchCooperativeKernel関数を使用する必要があります.

制約

Cooperative groupsで全スレッド同期を行える起動スレッド数には制限があります.
これは「Occupancyを1にするスレッド数」*「SMの数」です.
前者は使用するSharedメモリの量などで決まり(現在のGPUでは上限1024),SMの数はGPUによりまちまちです.
どちらもCUDAの関数で取得できます.
前者はcudaOccupancyMaxActiveBlocksPerMultiprocessor関数,後者はcudaGetDeviceProperties関数を用います.

カテゴリー:CUDA
記事作成日:2019-12-17