CUDA非法访问解决陌生问题

时间:2015-04-30 11:48:55

标签: cuda cuda-gdb

我的问题是:CUDA硬件是否有问题,还是可能有其他解释? 我有一个内核已经使用了大约一年没有修改。最近,我开始以不规则的间隔获得分段错误,即它可以被复制,有时在几分钟之后,有时在执行数小时之后。这导致该程序的最低版本仍然复制了段错误。以及从stackoverflow帖子中学习的东西。

cuda-memcheck,在重复bash循环中运行时,最终会报告:

========= Invalid __global__ read of size 4
=========     at 0x000048f0 in SegFault.cu:157:SegFault( float* )
=========     by thread (128,0,0) in block (3706,0,0)
=========     Address 0x003400e8 is out of bounds

排除了坏指针操作的常见罪魁祸首。另一个线索是非法寻址在代码中的位置不一致;在整个内核中,它对于全局数组的任何索引都是不规则地发生的。

在我的问题的这一点上,最可能的解释是错误的代码。让我相信硬件故障的原因来自cuda-gdb:

cuda-gdb ./SegFaultTest
(cuda-gdb) set cuda memcheck on
(cuda-gdb) run
Illegal access to address (@global)0x245684 detected.

Program received signal CUDA_EXCEPTION_1, Lane Illegal Address.
[Switching focus to CUDA kernel 0, grid 1, block (5537,0,0), thread (0,0,0), device 0, sm 22, warp 28, lane 0]
0x00000000004f1ff8 in kernel( float * @global )<<<(33480,1,1),(512,1,1)>>> ( c=0x250000 ) at SegFault.cu:37
37              c[ix] += share_c[0];

(cuda-gdb) print &c[ix]
$2 = (@global float *) 0x255684

索引“ix”是:

int ix = blockIdx.x + blockIdx.y*gridDim.x;

实例化后不会修改。实际上,0x245684低于c=0x250000的起始地址。然而,当我查询print &c[ix]时,它返回0x255684,这是该数组的可接受地址。在再次弹出之前,再现需要10-50次执行,但非法地址总是与0x010000返回的print &c[ix]不同{/ strong>。我无法解释其中的差异错误消息和打印之间的地址。结合一位差异,我怀疑硬件有问题。 FWIW,0x010000等于此特斯拉C1060的最大网格尺寸。

最后,我今天用新型号取代了CUDA卡。 100次执行后我无法重现。

1 个答案:

答案 0 :(得分:2)

如果启用了memcheck的cuda-gdb报告了非法地址访问,请执行以下操作:

Illegal access to address (@global)0x245684 detected.

Program received signal CUDA_EXCEPTION_1, Lane Illegal Address.
[Switching focus to CUDA kernel 0, grid 1, block (5537,0,0), thread (0,0,0), device 0, sm 22, warp 28, lane 0]
0x00000000004f1ff8 in kernel( float * @global )<<<(33480,1,1),(512,1,1)>>> ( c=0x250000 ) at SegFault.cu:37
37              c[ix] += share_c[0];

查询该地址会返回不同的值

(cuda-gdb) print &c[ix]
$2 = (@global float *) 0x255684

然后硬件坏了。