CUDA非法访问地址陌生
CUDA Illegal access to address strangeness
我的问题是:是CUDA硬件有问题,还是有其他解释?
我有一个内核,它已经使用了大约一年而没有修改。最近,我开始以不规则的间隔出现分段错误,即它可以重现,有时在几分钟后,有时在执行数小时后。这导致该程序的最低版本仍然重现了段错误。以及从 Whosebug 帖子中学到的很多东西。
cuda-memcheck,当运行在一个repeat 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]
= (@global float *) 0x255684
索引"ix"是:
int ix = blockIdx.x + blockIdx.y*gridDim.x;
并且在实例化后不被修改。实际上,0x245684
低于 c=0x250000
的起始地址。然而,当我查询 print &c[ix]
时,它 returns 0x255684
,这是该数组可接受的地址。复制需要执行 10-50 次才能再次弹出,但非法地址总是一位 0x010000
与 print &c[ix]
returns. 不同我无法解释错误消息和打印地址之间的差异。结合一位差异,我怀疑硬件有问题。 FWIW,0x010000
等于此 Tesla C1060 的最大网格尺寸。
最后,我今天用新型号更换了CUDA卡。我已经执行了100次后无法重现。
如果启用了 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];
并查询该地址 returns 不同的值:
(cuda-gdb) print &c[ix]
= (@global float *) 0x255684
那就是硬件坏了
我的问题是:是CUDA硬件有问题,还是有其他解释? 我有一个内核,它已经使用了大约一年而没有修改。最近,我开始以不规则的间隔出现分段错误,即它可以重现,有时在几分钟后,有时在执行数小时后。这导致该程序的最低版本仍然重现了段错误。以及从 Whosebug 帖子中学到的很多东西。
cuda-memcheck,当运行在一个repeat 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]
= (@global float *) 0x255684
索引"ix"是:
int ix = blockIdx.x + blockIdx.y*gridDim.x;
并且在实例化后不被修改。实际上,0x245684
低于 c=0x250000
的起始地址。然而,当我查询 print &c[ix]
时,它 returns 0x255684
,这是该数组可接受的地址。复制需要执行 10-50 次才能再次弹出,但非法地址总是一位 0x010000
与 print &c[ix]
returns. 不同我无法解释错误消息和打印地址之间的差异。结合一位差异,我怀疑硬件有问题。 FWIW,0x010000
等于此 Tesla C1060 的最大网格尺寸。
最后,我今天用新型号更换了CUDA卡。我已经执行了100次后无法重现。
如果启用了 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];
并查询该地址 returns 不同的值:
(cuda-gdb) print &c[ix]
= (@global float *) 0x255684
那就是硬件坏了