CUDAでFunctorを使う 捕捉

CUDAでFunctorを使う - fjnlの生存記録のような何かに対する捕捉です。

当初、CUDAはデバイスコードへのパラメータをshared memory経由で渡していました。しかし、Compute Capability 2.0*1からはconstant memory経由で渡されるように変更されています。shared memoryに比べればconstant memoryは容量に余裕がある事が多いため、これは嬉しい変更であると思います。

さて、メンバのないfunctorは、以下のようにPTX上では1バイトの変数として扱われています。Compute Capability 2.0以前向けのコードでshared memoryをカツカツに使っている場合には、functorを使いたくても使えないという場合があるかもしれません。(レアケースすぎるかなぁ…)

.param .align 1 .b8 __cudaparm__Z22element_wise_operationI3mulEvPdPKdS3_T__f[1]

なお、あるデバイス関数がどれだけのメモリを使っているかは、nvccのコンパイルオプションに-Xptxas -vを付けるとコンパイル時に表示されます。

サンプルコードを-arch=sm_13と-arch=sm_20でコンパイルした時の出力は以下です。
sm_20からは、パラメータを渡す時にshared memoryではなくconstant memoryが使われていることがわかります。

$ nvcc func.cu -arch=sm_20 -Xptxas -v
ptxas info    : Compiling entry function '_Z22element_wise_operationI3mulEvPdPKdS3_T_' for 'sm_20'
ptxas info    : Used 9 registers, 57 bytes cmem[0]
ptxas info    : Compiling entry function '_Z22element_wise_operationI3addEvPdPKdS3_T_' for 'sm_20'
ptxas info    : Used 9 registers, 57 bytes cmem[0]
$ nvcc func.cu -arch=sm_13 -Xptxas -v
ptxas info    : Compiling entry function '_Z22element_wise_operationI3mulEvPdPKdS3_T_' for 'sm_13'
ptxas info    : Used 5 registers, 25+16 bytes smem
ptxas info    : Compiling entry function '_Z22element_wise_operationI3addEvPdPKdS3_T_' for 'sm_13'
ptxas info    : Used 5 registers, 25+16 bytes smem

*1:GTX470やGTX480など