消えたCUDA関連の旧ブログ記事を復元するひとり Advent Calendar 2024の記事です。
なんの話か
Fortran/OpenACCのループ内サブルーチンで可変長配列を用いた場合、NVIDIA GPU上ではどこのメモリにどのタイミングで確保されるか調べてみました。
コンパイル時に配列長が決定していないためレジスタに作られることはないだろうとの予想のもと、カーネル内mallocを呼んでいるのかなーと言う気持ちで調べていきます。
実験コード
調査に用いたコードはこちらです。
inline展開されると困るので、2ファイルに分けて書いています。
▼sub.f90
▼main.f90
(Makefile等はこちら enp1s0/openacc-subroutine - GitHub)
2ファイル用意したものの、実際にはsub.f90があれば調査できます。
コンパイルしたsub.o内に含まれるPTXをcuobjdumpで覗きます。
予想通りmallocが呼ばれていることが確認できます。
つまり可変長配列の実体はDeviceメモリ上で、カーネル実行の最中に確保されるようです。
では、可変長配列をサイズ決め打ちの固定長にするとどうなるかと言うと、
- サイズが小さいときはレジスタ
- サイズが多いときは同様にカーネル内malloc
となることが確認できます。
おわり
カーネル内mallocというものを知った時誰が使うのだろうと思っていましたが、OpenACC/Fortranの実装で使われていたのですね。