CUDA memcheck地址-如何确定代码中的位置?
cuda memcheck正在报告发布模式cuda内核的以下信息:CUDA memcheck地址-如何确定代码中的位置?,cuda,gpgpu,gpu,Cuda,Gpgpu,Gpu,cuda memcheck正在报告发布模式cuda内核的以下信息: ========= Error: process didn't terminate successfully ========= Invalid __global__ read of size 4 ========= at 0x000002c8 in xx_kernel ========= by thread (0,0,0) in block (0,0) ========= Address 0x10101
========= Error: process didn't terminate successfully
========= Invalid __global__ read of size 4
========= at 0x000002c8 in xx_kernel
========= by thread (0,0,0) in block (0,0)
========= Address 0x10101600014 is out of bounds
=========
========= ERROR SUMMARY: 1 error
此故障仅在释放模式下发生。在cuda gdb下运行时也不会发生这种情况
如何获取0x000002c8地址并确定导致故障的代码?我查看了缓存的中间文件(.ptx、.cubin等),没有找到确定错误源代码的明显方法
这是在x86_64 Linux和CUDA 3.2上实现的
更新:原来这是3.2版本中的一个编译器错误。升级到4.0会消除memcheck错误。此外,我还能够使用4.0中的cuobjdump反汇编CUBIN,但由于它是发布模式并经过优化,因此很难将反汇编与源代码相匹配。内核中的此类错误与内存访问有关,而内存访问不仅基于线程标识符 考虑到您使用的每个内存区域都已为GPU正确分配了,仅基于threadIdx.x之类的内容进行访问应该不会引起任何问题。因此:
- 可能是索引计算错误(例如,
)data[blockDim.y*blockDim.x*threadIdx.z+blockDim.x*threadIdx.y+threadIdx.x]等表达式经常出现这种情况)
- 或者您在索引计算中使用了另一个变量,使其超出数组边界(例如
)数据[threadIdx.x+offset]
有关设备>2.x的补充信息,请参见@Cicada的答案下载。使用新的支持2.x立方的
cuobjdump
cuobjdump-sass/path/to/your/cubin>/path/to/dump.txt
输出示例(在20立方英寸的sm_上测试,代码版本2.3)
你可以发布你的内核代码,这样我们就可以看到为什么这个线程访问一个越界区域了吗?不幸的是,它的专有源代码,所以我不能发布实际的代码。谢谢,你错了@Cicada!拥有
块(0,0)
的线程(0,0,0)
并不意味着访问仅基于此线程idx
。无论线程(0,0,0)
是否尝试基于其唯一标识符访问内存位置,CUDA memcheck输出都是相同的。这可能与索引计算有关:再看看我的示例,它同时位于线程标识符和blockDim上。我考虑两种情况:与内核配置相关的(StudiDox、BuffDIM、GrimDIM、BuffDIX、……)以及与其他源相关的变量(常数、参数、……),我需要的是CuBin反汇编程序,但是CubOutDUMP不适用于2×CubBs。有其他选择吗?我将下载4.0并尝试一下。谢谢。转到4.0修复了此故障。谢谢
...
/*6018*/ /*0xe00100075003ff9a*/ CAL 0x46d8;
/*6020*/ /*0x10001de428000000*/ MOV R0, R4;
/*6028*/ /*0x00001de428000000*/ MOV R0, R0;
/*6030*/ /*0x40011de428000000*/ MOV R4, R16;
...