私はCuda4プログラムのプロファイリングを行っていましたが、ある段階で、実行中のプロセスが80GiBを超える仮想メモリを使用していることが判明しました。それは私が予想していたよりもはるかに多かった。時間の経過に伴うメモリマップの進化を調べ、実行しているコード行を比較した後、これらの簡単な命令の後、仮想メモリの使用量は80GiBを超えることがわかりました。
int deviceCount;
cudaGetDeviceCount(&deviceCount);
if (deviceCount == 0) {
perror("No devices supporting CUDA");
}
明らかに、これは最初のCuda呼び出しであるため、ランタイムが初期化されました。この後、メモリマップは次のようになります(切り捨てられます)。
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 89796 14716 0 r-x-- prg
0000000005db1000 12 12 8 rw--- prg
0000000005db4000 80 76 76 rw--- [ anon ]
0000000007343000 39192 37492 37492 rw--- [ anon ]
0000000200000000 4608 0 0 ----- [ anon ]
0000000200480000 1536 1536 1536 rw--- [ anon ]
0000000200600000 83879936 0 0 ----- [ anon ]
これで、この巨大なメモリ領域が仮想メモリ空間にマッピングされました。
Linuxでメモリを予約/割り当てても、実際にこのメモリに書き込まない限り、あまり効果がないため、それほど大きな問題ではないかもしれません。しかし、たとえばMPIジョブは、ジョブで使用可能なvmemの最大量で指定する必要があるため、これは非常に面倒です。そして、80GiBは、Cudaジョブの場合よりも低い境界です。他のすべてのものも追加する必要があります。
それは、Cudaが維持しているいわゆるスクラッチスペースに関係していると想像できます。動的に拡大および縮小できるカーネルコード用の一種のメモリプール。しかし、それは憶測です。また、デバイスメモリに割り当てられます。
洞察はありますか?