問題:セグメンテーション違反 (SIGSEGV、シグナル 11)
プログラムの簡単な説明:
- リモート クライアントからの要求を処理する高性能 GPU (CUDA) サーバー
- 各着信要求は、複数の GPU (並列ではなくシリアル) で計算を実行するスレッドを生成し、結果をクライアントに返します。各要求は数十または数百のカーネル呼び出しで構成されるため、通常、これには 10 ~ 200 ミリ秒かかります。
- リクエスト ハンドラー スレッドは GPU に排他的にアクセスできます。つまり、1 つのスレッドが GPU1 で何かを実行している場合、他のすべてのスレッドはそれが完了するまで待機する必要があります。
- -arch=sm_35 -code=compute_35 でコンパイル
- CUDA 5.0 の使用
- スラスト(さまざまな関数)とcudaDeviceSynchronize()を明らかに使用していますが、明示的にCUDAアトミックまたはカーネル内同期バリアを使用していません
- Nvidia ドライバー: NVIDIA dlloader X ドライバー 313.30 Wed Mar 27 15:33:21 PDT 2013
OS およびハードウェア情報:
- Linux lub1 3.5.0-23-generic #35~precise1-Ubuntu x86_64 x86_64 x86_64 GNU/Linux
- GPU: 4x GPU 0: GeForce GTX TITAN
- 32GBのRAM
- MB: ASUS マキシマス V エクストリーム
- CPU: i7-3770K
クラッシュ情報:
クラッシュは、数千のリクエストが処理された後に「ランダムに」発生します (より早い場合もあれば、より遅い場合もあります)。一部のクラッシュのスタック トレースは次のようになります。
#0 0x00007f8a5b18fd91 in __pthread_getspecific (key=4) at pthread_getspecific.c:62
#1 0x00007f8a5a0c0cf3 in ?? () from /usr/lib/libcuda.so.1
#2 0x00007f8a59ff7b30 in ?? () from /usr/lib/libcuda.so.1
#3 0x00007f8a59fcc34a in ?? () from /usr/lib/libcuda.so.1
#4 0x00007f8a5ab253e7 in ?? () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#5 0x00007f8a5ab484fa in cudaGetDevice () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#6 0x000000000046c2a6 in thrust::detail::backend::cuda::arch::device_properties() ()
#0 0x00007ff03ba35d91 in __pthread_getspecific (key=4) at pthread_getspecific.c:62
#1 0x00007ff03a966cf3 in ?? () from /usr/lib/libcuda.so.1
#2 0x00007ff03aa24f8b in ?? () from /usr/lib/libcuda.so.1
#3 0x00007ff03b3e411c in ?? () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#4 0x00007ff03b3dd4b3 in ?? () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#5 0x00007ff03b3d18e0 in ?? () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#6 0x00007ff03b3fc4d9 in cudaMemset () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#7 0x0000000000448177 in libgbase::cudaGenericDatabase::cudaCountIndividual(unsigned int, ...
#0 0x00007f01db6d6153 in ?? () from /usr/lib/libcuda.so.1
#1 0x00007f01db6db7e4 in ?? () from /usr/lib/libcuda.so.1
#2 0x00007f01db6dbc30 in ?? () from /usr/lib/libcuda.so.1
#3 0x00007f01db6dbec2 in ?? () from /usr/lib/libcuda.so.1
#4 0x00007f01db6c6c58 in ?? () from /usr/lib/libcuda.so.1
#5 0x00007f01db6c7b49 in ?? () from /usr/lib/libcuda.so.1
#6 0x00007f01db6bdc22 in ?? () from /usr/lib/libcuda.so.1
#7 0x00007f01db5f0df7 in ?? () from /usr/lib/libcuda.so.1
#8 0x00007f01db5f4e0d in ?? () from /usr/lib/libcuda.so.1
#9 0x00007f01db5dbcea in ?? () from /usr/lib/libcuda.so.1
#10 0x00007f01dc11e0aa in ?? () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#11 0x00007f01dc1466dd in cudaMemcpy () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#12 0x0000000000472373 in thrust::detail::backend::cuda::detail::b40c_thrust::BaseRadixSortingEnactor
#0 0x00007f397533dd91 in __pthread_getspecific (key=4) at pthread_getspecific.c:62
#1 0x00007f397426ecf3 in ?? () from /usr/lib/libcuda.so.1
#2 0x00007f397427baec in ?? () from /usr/lib/libcuda.so.1
#3 0x00007f39741a9840 in ?? () from /usr/lib/libcuda.so.1
#4 0x00007f39741add08 in ?? () from /usr/lib/libcuda.so.1
#5 0x00007f3974194cea in ?? () from /usr/lib/libcuda.so.1
#6 0x00007f3974cd70aa in ?? () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#7 0x00007f3974cff6dd in cudaMemcpy () from /usr/local/cuda-5.0/lib64/libcudart.so.5.0
#8 0x000000000046bf26 in thrust::detail::backend::cuda::detail::checked_cudaMemcpy(void*
ご覧のとおり、通常、ライブラリ自体__pthread_getspecific
から呼び出されるlibcuda.so
か、ライブラリ自体のどこかで終了します。私が覚えている限りでは、クラッシュせずに奇妙な方法でハングしたケースが 1 つだけありました。GPU 計算 (統計など) が含まれていない場合、プログラムは私の要求に応答できましたが、それ以外の場合は応答できました。返信がありませんでした。また、 nvidia-smi -L を実行しても機能せず、コンピューターを再起動するまでハングしていました。GPUデッドロックのようなものに見えました。ただし、これはこれとはまったく異なる問題かもしれません。
問題がどこにあるのか、または何が原因なのか、誰にも手がかりがありますか?
アップデート:
いくつかの追加分析:
cuda-memcheck
エラーメッセージを出力しません。valgrind
- リークチェックは、以下のようなかなりの数のメッセージを出力します (そのようなものは何百もあります):
==2464== 16 bytes in 1 blocks are definitely lost in loss record 6 of 725 ==2464== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==2464== by 0x568C202: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) ==2464== by 0x56B859D: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) ==2464== by 0x5050C82: __nptl_deallocate_tsd (pthread_create.c:156) ==2464== by 0x5050EA7: start_thread (pthread_create.c:315) ==2464== by 0x6DDBCBC: clone (clone.S:112) ==2464== ==2464== 16 bytes in 1 blocks are definitely lost in loss record 7 of 725 ==2464== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==2464== by 0x568C202: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) ==2464== by 0x56B86D8: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) ==2464== by 0x5677E0F: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) ==2464== by 0x400F90D: _dl_fini (dl-fini.c:254) ==2464== by 0x6D23900: __run_exit_handlers (exit.c:78) ==2464== by 0x6D23984: exit (exit.c:100) ==2464== by 0x6D09773: (below main) (libc-start.c:258) ==2464== 408 bytes in 3 blocks are possibly lost in loss record 222 of 725 ==2464== at 0x4C29DB4: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==2464== by 0x5A89B98: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x5A8A1F2: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x5A8A3FF: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x5B02E34: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x5AFFAA5: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x5AAF009: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x5A7A6D3: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x59B205C: ??? (in /usr/lib/libcuda.so.313.30) ==2464== by 0x5984544: cuInit (in /usr/lib/libcuda.so.313.30) ==2464== by 0x568983B: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35) ==2464== by 0x5689967: ??? (in /usr/local/cuda-5.0/lib64/libcudart.so.5.0.35)
詳しくは:
より少ない数のカード (プログラムに必要な最小限の 3 枚) で実行しようとしましたが、それでもクラッシュが発生します。
上記は当てはまりません。アプリケーションの設定を誤ったため、4 枚のカードすべてが使用されました。本当にたった 3 枚のカードで実験を再実行すると、問題が解決するようです。現在、クラッシュすることなく、重い負荷の下で数時間実行されています。もう少し実行してから、3 枚のカードの別のサブセットを使用してこれを確認し、同時に問題が特定のカードに関連しているかどうかをテストします。
テスト実行中に GPU の温度を監視しましたが、問題はないようです。ファンが約 56% の最大負荷でカードは約 78 ~ 80 °C まで上昇し、これはクラッシュが発生するまで (数分) 続きますが、私には高すぎるとは思えません。
私が考えていることの1つは、リクエストが処理される方法です-各リクエストが新しいスレッドを生成し(私はマングースライブラリを使用しています)、このスレッドが cudaSetDevice( id) に適切なデバイス ID を付けます。切り替えは、1 つの要求中に複数回発生する可能性があり、ストリームを使用していません (したがって、すべてデフォルト (0) ストリーム IIRC に移動します)。これは、 pthread_getspecific で発生するクラッシュに何らかの形で関連している可能性がありますか?
最新のドライバー (ベータ版、319.12) へのアップグレードも試みましたが、役に立ちませんでした。