从libcuda.so.1调用的__pthread_getspecific中的分段错误

时间:2013-04-23 08:09:15

标签: c++ cuda segmentation-fault

问题:分段错误(SIGSEGV,信号11)

简要程序说明:

  • 高性能gpu(CUDA)服务器处理来自远程的请求 客户
  • 每个传入的请求都会产生一个执行的线程 计算多个GPU(串行,不并行)和发送 将结果返回给客户端,这通常需要10到200毫秒,因为每个请求包含数十或数百个内核调用
  • 请求处理程序线程具有对GPU的独占访问权,这意味着如果一个线程在GPU1上运行某些东西,则所有其他线程都必须等到它完成
  • 使用-arch = sm_35 -code = compute_35
  • 编译
  • 使用CUDA 5.0
  • 我没有明确使用任何CUDA原子或任何内核同步障碍,虽然我正在使用推力(各种函数)和cudaDeviceSynchronize()显然
  • Nvidia司机:NVIDIA dlloader X Driver 313.30 Wed Mar 27 15:33:21 PDT 2013

操作系统和硬件信息:

  • Linux lub1 3.5.0-23-generic#35~minision1-Ubuntu x86_64 x86_64 x86_64 GNU / Linux
  • GPU:4x GPU 0:GeForce GTX TITAN
  • 32 GB RAM
  • MB:ASUS MAXIMUS V EXTREME
  • 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或库中的某个地方。据我所知,只有一个案例没有崩溃,而是以一种奇怪的方式绞死:如果程序不涉及任何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,因为这是程序所需的最小值),但仍然会发生崩溃。

以上情况并非如此,我错误配置了应用程序并使用了所有四张卡。真正只用3张卡重新运行实验似乎解决了这个问题,现在它在重载下运行了几个小时而没有崩溃。我现在试着让它运行一点,然后尝试使用3张牌的不同子集来验证这一点,同时测试问题是否与某张特定牌有关。

我在测试运行期间监控GPU温度,似乎没有任何错误。在最高负载下,卡达到约78-80°C,风扇大约达到56%,这一直持续到发生碰撞(几分钟),对我来说似乎不是太高。

我一直在考虑的一件事是处理请求的方式 - 有很多cudaSetDevice调用,因为每个请求产生一个新线程(我使用mongoose库)然后这个线程在卡之间切换使用适当的设备ID调用cudaSetDevice(id)。切换可以在一个请求期间多次发生,并且我没有使用任何流(因此它全部转到默认(0)流IIRC)。这可能与pthread_getspecific中发生的崩溃有关吗?

我也尝试升级到最新的驱动程序(测试版,319.12),但这没有帮助。

1 个答案:

答案 0 :(得分:5)

如果您可以识别3张可行的卡,请尝试使用第4张卡代替其中一张卡,并查看是否再次出现故障。这只是我认为的标准故障排除。如果你能识别出一张卡片,当它包含在一组3片中时,仍会引发问题,那么该卡片就是可疑的。

但是,我建议使用更少的卡来运行也是基于它可以减少PSU上的总体负载的想法。即使在1500W,你也可能没有足够的果汁。因此,如果您循环第4张卡,代替3张中的一张(即系统中仅保留3张卡或配置您的应用程序使用3张)并且您没有失败,则问题可能是由于整体功耗4张牌。

请注意,GTX Titan满载时的功耗可能在250W或更高。因此看起来您的1500W PSU应该没问题,但可能会仔细分析每个轨道上可用的DC电源量,以及主板和PSU线束如何将12V DC轨道分配给每个GPU。 / p>

因此,无论你使用哪3个,减少到3GPUs似乎都能解决问题,我的猜测是你的PSU不能胜任这个任务。并非所有1500W都可以通过单个DC轨道获得。 12V“导轨”实际上由几个不同的12V导轨组成,每个导轨都提供1500W的整体特定部分。因此,即使您可能没有拉动1500W,您仍然可以使单个导轨过载,具体取决于GPU电源连接到导轨的方式。

我同意80C范围内的温度应该没问题,但这表明(大约)一个满载的GPU,所以如果你同时在所有4个GPU上看到它,那么你就会负担很重。