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

2024-03-09 06:04

本文主要是介绍解决由NVCC编译优化所产生的Bug,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Bug描述

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

__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保存的是out[idx]的原始值,%rd4保存的是out[idx]在内存中的地址,所以这两条指令的意思就是out[idx]加上2147450880的值再存回去。

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

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

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

这篇关于解决由NVCC编译优化所产生的Bug的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/789730

相关文章

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

kkFileView启动报错:报错2003端口占用的问题及解决

《kkFileView启动报错:报错2003端口占用的问题及解决》kkFileView启动报错因office组件2003端口未关闭,解决:查杀占用端口的进程,终止Java进程,使用shutdown.s... 目录原因解决总结kkFileViewjavascript启动报错启动office组件失败,请检查of

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

java内存泄漏排查过程及解决

《java内存泄漏排查过程及解决》公司某服务内存持续增长,疑似内存泄漏,未触发OOM,排查方法包括检查JVM配置、分析GC执行状态、导出堆内存快照并用IDEAProfiler工具定位大对象及代码... 目录内存泄漏内存问题排查1.查看JVM内存配置2.分析gc是否正常执行3.导出 dump 各种工具分析4.

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

小白也能轻松上手! 路由器设置优化指南

《小白也能轻松上手!路由器设置优化指南》在日常生活中,我们常常会遇到WiFi网速慢的问题,这主要受到三个方面的影响,首要原因是WiFi产品的配置优化不合理,其次是硬件性能的不足,以及宽带线路本身的质... 在数字化时代,网络已成为生活必需品,追剧、游戏、办公、学习都离不开稳定高速的网络。但很多人面对新路由器