12

私は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が維持しているいわゆるスクラッチスペースに関係していると想像できます。動的に拡大および縮小できるカーネルコード用の一種のメモリプール。しかし、それは憶測です。また、デバイスメモリに割り当てられます。

洞察はありますか?

4

1 に答える 1

14

スクラッチスペースとは何の関係もありません。これは、ホストと複数のGPU間で統一されたアドレス指定とピアツーピアアクセスを可能にするアドレス指定システムの結果です。CUDAドライバーは、カーネルの仮想メモリシステムを使用して、すべてのGPUメモリとホストメモリを単一の仮想アドレス空間に登録します。それ自体は実際にはメモリ消費ではなく、使用可能なすべてのアドレス空間を線形仮想空間にマッピングして統一されたアドレス指定を行うための単なる「トリック」です。

于 2012-07-24T13:27:27.437 に答える