CUDAバイナリアンへの入り口

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

CUDAのカーネル関数のバイナリを書き換えるメリット

ほぼないですよね?
多分ただつらいだけです.
でも万が一書き換えたくなってしまったときにどうやって書き換えていけばいいかを書いておきます.

出来上がっているカーネル関数のバイナリを書き換える

やることは簡単で,cuobjdumpでdisassembleした結果と実行ファイルなどをバイナリエディタ(vimなど)で開いた結果を突き合わせて書き換えるだけです.

例えばこんな行を書き換えたければ,(Voltaの)命令長128bitのうち前半64bitの下16bitである7223をリトルエンディアンであることを考慮して2372で検索します.
すると,まぁ,見つかります.

あとは適当に書き換えていくだけです.

なにをどう書き換えればいいかは,例えばVoltaであれば
Zhe Jia, Marco Maggioni, Benjamin Staiger, Daniele P. Scarpazza, Dissecting the NVIDIA Volta GPU Architecture via Microbenchmarking
などの論文に載っています.
(これに沿ってレジスタにreuseフラグをつけてみようと思ったけどうまく行きませんでしたが.)

これからコンパイルするカーネル関数のバイナリを編集する

nvcc test.cu -arch=sm_70 -cuda
nvccは-cudaオプションで*.cu.cpp.iiというhostのコンパイラでコンパイルできるソースコードをはいてくれるのですが,ここにはインラインアセンブラでカーネル関数のバイナリが埋め込まれます. 中を見ると先程検索した7223が見当たりますよね.
こっちはビッグエンディアンです.
これを書き換えれてgccやnvccでコンパイルすればいい感じです.

書き換えても動くの?

定数4.0fを代入するだけのコードで

単精度0x40800000 (4.0f) → 単精度0xc0800000 (-4.0f)
みたいな変更を加えてみましたが,期待通り-4.0fが代入されていました.

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