3

プログラムのバグを見つけようとしています。それは生産します

[vaio:10404] Signal: Segmentation fault (11) 
[vaio:10404] Signal code: Address not mapped (1) 
[vaio:10404] Failing at address: 0x210000
[vaio:10405] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x7fa7857ffcb0]
[vaio:10405] [ 1] /lib/x86_64-linux-gnu/libc.so.6(+0x14fe20) [0x7fa785580e20]
[vaio:10405] [ 2] /usr/lib/libcuda.so.1(+0x1b1f49) [0x7fa78676bf49]

0x210000GPU メモリに存在するアドレスです。統一されたアドレス空間がありません (カードの制限のため: sm_12)。

を介してプログラムを実行すると、問題が発生しますmpiexec -n 2。つまり、2 つの CPU プロセスを開始し、どちらも同じ (!) GPU (1 つの GPU がインストールされているだけ) で独自のコンテキストを作成します。このような:

cuInit(0);
cuDeviceGet(&cuDevice, 0); // get device number 0
cuCtxCreate(&cuContext, 0, cuDevice); // create context
cuMemAlloc( &mem , size );  // allocate memory pool (hundreds of MB)

(これはここでは単純化されています - すべての cuda 呼び出しでエラーが返されたかどうかがチェックされます)

私はこのセットアップをかなり長い間うまく使用しています (複数のホスト プロセスが同じ GPU を共有しています)。ただし、それは CUDA ランタイム API を使用する場合でした。現在、ドライバー API に切り替えています。

これを突き止めるためmemに、上記のコードからダンプします。によって返されるメモリ アドレスcuMemAllocは、両方のプロセスで同じであることが判明しました。これは私を驚かせます。ここにダンプします:

process 0: allocate internal buffer: unaligned ptr = 0x210000  aligned ptr = 0x210000
process 1: allocate internal buffer: unaligned ptr = 0x210000  aligned ptr = 0x210000

すぐに、そのような問題のない古いコード (ランタイム API) を確認しました。両方のプロセス(同じデバイスを共有)で同じメモリアドレスも報告することが判明しました。これはこれまで私の注意を引くことはありませんでした。

これは信じがたいことです。これを明確にするために:両方のプロセスがcudaMalloc(ランタイムAPI)とcuMalloc(ドライバーAPI)(大きなカードで400MB)でデバイスメモリを要求し、両方のプロセスが同じアドレスを返しますか?最初のプロセスがすでに終了しているため、最初のプロセスが同じメモリを再利用できるように、1 つのプロセスが大幅に進行して既にメモリを解放していないことは確かです。いいえ、このメモリは、後続のメモリ割り当てに対応するためのメモリ プールとして使用され、その間に多くの同期ポイントがあります。プールはプログラムの終了時に解放されます。

同じポインタ値 (メモリ アドレス) を両方のプロセスに報告する方法を知っている人はいますが、GPU ではこれは異なるメモリを参照していますか? (それが実行する計算は正しいため、そうする必要があります。また、メモリ プールが重複している場合はそうではありません)。私の知る限り、これは不可能です。私は何が欠けていますか?

4

1 に答える 1

4

仮想アドレス指定の概念がありません。

各 CPU スレッドには独自の CUcontext があり、各 CUcontext には独自の GPU仮想アドレス空間があります。API から返されるアドレスは仮想アドレスであり、ホスト ドライバーやデバイスは仮想アドレスを GPU メモリ内の絶対アドレスに変換します。まさにこの目的のために GPU に専用の TLB が搭載されているという証拠はたくさんあります。

于 2012-10-20T12:46:03.530 に答える