消えたCUDA関連の旧ブログ記事を復元するひとり Advent Calendar 2024の記事です。

何の話か

NVIDIA謹製の疑似乱数生成ライブラリcuRANDにはカーネル関数内で呼ぶ関数群とホストから呼ぶ関数群があります。
疑似乱数生成アルゴリズムはメルセンヌ・ツイスタなどいくつかあるのですが、この記事はホストから呼ぶ関数でアルゴリズムによるスループットの違いを調べたので、簡単にちょろっとまとめます。

検証コード

enp1s0 / curand-perf - GitHub

内容としてはcurandGenerateUniformを用いて単精度の一様乱数列を生成します。
比較する疑似乱数アルゴリズムは以下のものです。

  • CURAND_RNG_PSEUDO_DEFAULT
  • CURAND_RNG_PSEUDO_XORWOW
  • CURAND_RNG_PSEUDO_MRG32K3A
  • CURAND_RNG_PSEUDO_MTGP32
  • CURAND_RNG_PSEUDO_MT19937
  • CURAND_RNG_PSEUDO_PHILOX4_32_10
  • CURAND_RNG_QUASI_DEFAULT
  • CURAND_RNG_QUASI_SOBOL32
  • CURAND_RNG_QUASI_SCRAMBLED_SOBOL32

結果

横軸が生成する乱数列の長さ、縦軸が生成スループット[GB/s]です。
使用したGPUはNVIDIA A100 40GBで、デバイスメモリのバンド幅は1555[GB/s]です。
乱数アルゴリズムにこだわりがなく、ある程度の長さの乱数列を生成する場合はCURAND_RNG_PSEUDO_PHILOX4_32_10を指定しておくと良さそうです。
調べた範囲では最大80%くらいバンド幅を使っています。

CURAND_RNG_PSEUDO_DEFAULTCURAND_RNG_PSEUDO_XORWOWと同じと (1)に書いてありますし、スループットも同じとなっています。

並列疑似乱数アルゴリズムの話やスループットに関してもっと知りたい場合は

  • John K. Salmon, Mark A. Moraes, Ron O. Dror, and David E. Shaw, Parallel Random Numbers: As Easy as 1, 2, 3, SC11, 2011 [paper]
あたりをどうぞ。

また、現在のcuRANDはFP16に非対応です。
FP16の乱数を生成したい場合は

あたりのご利用を検討してみてください。

参考

  1. 5.1. Host API - CUDA Toolkit Documentation