解决由NVCC编译优化所产生的Bug

Bug描述

在测量如下一个简单的核函数的执行时间的时候,发现测量的时间和循环的次数完全无关,觉得很奇怪,因为循环的次数已经很大了,不管我再怎么提升循环次数,这么大的计算量,不可能保持时间的恒定。

c 复制代码
__global__ void setRowReadRow(int * out)
{
    unsigned int idx=threadIdx.y*blockDim.x+threadIdx.x;

    for(unsigned int l0=0; l0<65536; l0++)
    for(unsigned int l1=0; l1<65536; l1++)
    for(unsigned int l2=0; l2<65536; l2++)
    for(unsigned int l3=0; l3<65536; l3++)
    for(unsigned int m=0; m<65536; m++){
      out[idx] +=  m  ;
    }
}

于是去查看该Kernel的PTX代码,发现该函数主体只有一条ret指令,用于函数返回,没有任何计算过程:

复制代码
.visible .entry setRowReadRow(int*)(
        .param .u64 setRowReadRow(int*)_param_0
)
{

        ret;

}

这就解释得通为什么执行时间不变了,于是尝试调小循环次数,只保留变量m这一层嵌套,此时PTX代码如下:

复制代码
.visible .entry setRowReadRow(int*)(
        .param .u64 setRowReadRow(int*)_param_0
)
{

        ld.param.u64    %rd1, [setRowReadRow(int*)_param_0];
        cvta.to.global.u64      %rd2, %rd1;
        mov.u32         %r1, %tid.y;
        mov.u32         %r2, %ntid.x;
        mov.u32         %r3, %tid.x;
        mad.lo.s32      %r4, %r1, %r2, %r3;
        mul.wide.u32    %rd3, %r4, 4;
        add.s64         %rd4, %rd2, %rd3;
        ld.global.u32   %r5, [%rd4];
        add.s32         %r6, %r5, 2147450880;
        st.global.u32   [%rd4], %r6;
        ret;

}

这里不解释每条指令的具体含义了,可以用GPT等大模型帮忙翻译一下,重点解释这两条指令:

复制代码
        add.s32         %r6, %r5, 2147450880;
        st.global.u32   [%rd4], %r6;

%r5保存的是outidx的原始值,%rd4保存的是outidx在内存中的地址,所以这两条指令的意思就是outidx加上2147450880的值再存回去。

因为这部分代码只保留了m变量所在的那一层循环,分析可得,Kernel函数得到的结果就是把outidx的值再加上(0+1+2+3+...+65535)=2147450880。

很显然,编译器帮我们做了优化,把65536次循环加法变成了一次加法指令,再加上英伟达官方论坛的解答可以大致推测出,循环次数过多导致PTX代码只有一条ret指令的原因是编译器在做优化时,把循环的加法拿出去计算,导致了溢出了所以产生了不可预期的错误。

但是测试的时候发现把加法改成乘法后不会产生ret错误,分析ptx是因为对于乘法没有做这方面的优化,老老实实按照循环嵌套写的PTX代码,所以此时虽然outidx的计算会出现溢出,但是并不影响程序的运行。加法由于编译器会对循环优化,所以出现PTX的异常。

相关推荐
智码看视界11 小时前
深度学习:环境搭建PyTorch vs TensorFlow 选型
pytorch·深度学习·tensorflow·gpu·环境搭建·cuda·框架选型
Zip-List13 小时前
工作小记-pytorch的算子优化: 转gpu核函数 python调c
c语言·c++·pytorch·python·cuda
JosieBook1 天前
【多线程】两台机器同时抢一个字典:一次并发 Bug 的排查
java·网络·bug
鬼手点金2 天前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
_nibel2 天前
第三章:Details 剩余数据补读 ⭐教你读懂 Nsight Compute 报告 系列合集⭐
cuda·ncu·nsight compute
小玮看世界3 天前
【Bug 报告】腾讯元宝 Windows 客户端 v2.88.1 新建对话卡死、界面残留与输入框乱码
bug
衣舞晨风3 天前
一次升级引出两个BUG:API7 AI 网关流式 500 与低流量 CPU 打满排查
网关·ai·bug·异常排查
Starry-sky(jing)5 天前
onnxruntime 安装后 GPU 没加速?3 条命令确认它跑在 CPU 还是 GPU
python·gpu·cuda·onnxruntime·推理加速
小此方8 天前
「插曲:Git」企业规范篇:DevOps开发模型、Git Flow五类分支设计与测试/预发布/生产环境Bug修复及Hotfix紧急发布流程
git·bug·devops
中文英文-我选中文9 天前
FreeRTOS 玄学Bug:调换任务创建顺序,程序时而正常、时而死机(栈溢出内存踩踏深度复盘)
bug