CUDAのstreamにhost関数を流すには

目次

何がしたいか

CUDAにはstreamと呼ばれるスケジューリング機能があり、これを用いることでメモリの非同期コピーなどができます。
CUDA 10からはCUDA Graphと呼ばれるstreamをグラフとして記述し実行する機能もあり、複数のカーネル関数を1つ1つ立ち上げるのと比較してGraphとして立ち上げたほうが高速に立ち上げられるという結果もあります[1]
で、今回はそんなstreamにCPU側の処理を流したい場合にどうすればいいかという話です。

サンプルコード

cuLaunchHostFunc関数[2]を使うと流すことができます。

コンパイル時には

nvcc main.cu -std=c++11 -arch=sm_70 -lcuda
の様にlibcudaをリンクさせる必要があります。
cuLaunchHostFunc関数に渡すhost側の関数の引数はvoid*とし、cuLaunchHostFunc関数の第3引数に渡します。
気持ちとしてはWindows APIのCreateThreadの気持ちです(伝われ)。

cuLaunchHostFunc関数はExecution Controlの一部ですが、CUDA 10.1でAPIが刷新されており、これによって追加された関数です。
そのためCUDA 10.0以前では使えないのでお気をつけください。

おわりに

ところで私は勝手にstreamに流すって言ってしまっていますが、流すという表現であっているんですかね?

参考

  1. NVIDIA A100 Tensor Core GPU Architecture, NVIDIA, (p60 : Task Graph Acceleration on NVIDIA Ampere Architecture GPUs)
  2. cuLaunchHostFunc - Execution Control, CUDA TOOLKIT DOCUMENTATION
カテゴリー:CUDA
記事作成日:2020-06-29