CUDA性能分析之使用NVIDIA Nsight Compute

2024年3月12日 685点热度 0人点赞 0条评论

前言

NVIDIA Nsight Compute 和NVIDIA Nsight Systems作为CUDA工具包中的性能分析工具,但是他们的定位有所不同。

NVIDIA Nsight Systems 更强调的是整个程序的性能分析,不仅对于CUDA的运行信息,以及CPU中所执行的任务也是可以进行数据采样的。

NVIDIA NSight Compute 是一个专门针对核函数的性能分析工具,它对核函数的信息采集得非常详细,可以对列如缓存命中、显存吞吐量、计算吞吐量等信息进行追踪。它可以对每个核函数生成报表,这些报表中的信息如果有明显可以优化的地方,甚至会给出一些优化上的建议。

使用之前

使用管理员权限运行NVIDIA Nsight Compute,否则在执行CUDA程序时会报权限不足的错误。

如果未使用管理员权限运行,那么会收到没有权限访问GPU计数器的报错信息:

ERR_NVGPUCTRPERM - The user does not have permission to access NVIDIA GPU Performance Counters on the target device 0. For instructions on enabling permissions and to get more information see

基本设置

在软件界面使用new project 新建一个分析工程,设置好工程名称之后,会弹出基本信息设置窗口。

image-20240312104311316

  • Connection 选择localhost
  • Application Executable :执行程序路径
  • Working Directory:工作路径
  • Command Line:被分析程序运行时的附加参数

image-20240312104328603

  • Output File :文件输出路径,用于输出软件采集的运行时分析数据,可以在文件中加入%i,这么进行多次分析时输出的文件会根据数量调整i值,就不会出现分析数据被覆盖的问题。

image-20240312104629585

这个页面需要勾选需要对那些信息进行采样,我一般用默认的basic,如果想得到比较全面的信息则勾选full。

分析报表

Page:summary 核函数调用时间已经占用率等参数

image-20240227085110137

Page:Details 核函数调用的详细信息

image-20240312105842139

  • SM单元计算吞吐量 10%,这个值过于的低了,一般优化到70~80比较正常,这说明核函数的调用参数或者核函数里的结构有很大的优化空间。根据我的经验可以通过增大gridSize或者调整参数提高SM单元内的线程束占用率来提高计算吞吐量。
  • 内存占用率 97%,这似乎是内存带宽占用率,说明这个核函数中有很高的数据访问需求,如果能整合数据,使用共享内存或者其他方法,提高访问的速度,这也是一个可以优化的点。
  • L1 L2缓存命中率,在这里都达到了90+,已经是一个很高的值了,因为这个核函数只是数组相加函数,所以命中率特别的高,比较复杂的核函数是很难有这么高的缓存命中的。并且这也是特别难优化的一个点,这个跟核函数中算式的分段、调用参数的设置和访问数据的方式都有关系。需要根据具体的核函数制定具体的优化方法。

image-20240312110645487

上图为调用参数信息,以及共享内存使用量等信息。

线程束占用率

image-20240312110806800

  • 注意图中有理论占用率和实际占用率,理论占用率为100%,但是实际占用率却只用33%,这就是为什么SM单元计算吞吐量那么低的原因,因为线程束占用率少,则没有那么多的线程可以用于隐藏核函数内的数据访问延迟,那么大多数线程都长时间处于数据访问的等待状态,所以导致了计算吞吐量少。
  • 在列表下方给出了优化建议,大概意思是NVIDA Nsight Compute认为核函数在每个线程中的负载不均衡,这导致一个线程束中的线程,有的已经早早结束了计算,有的还在忙碌,还整个线程束是一个整体,它们是按线程束单位启动的,这样就导致了占用率低的问题。
  • 三个图表,这个是哪个图标分别是寄存器、block SIze和共享内存对线程束占用率的影响曲线,可以根据这些曲线优化资源的使用,已得到更高的线程束占用率。

Occupancy Calculator 占用率计算

image-20240312111747460

这个按钮可以通过输入的核函数参数来计算理论占用率,并给出调用参数建议

image-20240227092131735

这里需要输入blockSize、每个线程中寄存器和共享内存的使用量。

需要注意的是这里计算出来的是理论占用率,而实际占用率会收到核函数的结构和一些其他因素的影响,不过总是要将理论占用率提上去之后才有可能得到一个较高的实际占用率不是吗?

大脸猫

这个人虽然很勤快,但什么也没有留下!

文章评论