第一章:报告初印象与 Summary 细读 ⭐教你读懂 Nsight Compute 报告 系列合集⭐

第一章:报告初印象与 Summary 细读

序章里报告已经采好打开了,本章就从上到下、从左到右,把这个界面过一遍。界面里的信息很多,有轻有重,重要的就细讲,了解的就带过,具体的针对性的讲解之后单独成章。

界面初印象

打开 reduce-ill.ncu-rep 后的整体界面

最顶上一排是 Main Menu:File、Connection、Debug、Profile、Tools、Window、Help。

  • File 管理报告文件和工程,打开、关闭、另存为这些入口都在这里。不过作者的报告是直接用命令行打开的,工程已经自动建好、报告也已经打开了,所以用不到;
  • Connection 管理和目标机器的连接,ncu 支持本地或者 SSH 连上正在运行的程序边跑边采,但作者走的是先完整采集、再单独打开报告文件的路线,所以用不上;
  • Debug 管理现场调试,能把程序暂停、单步执行,盯每一次调用,对这份已经采完的报告同样用不上;
  • Profile 管理具体的采集配置,比如调整采集细致程度,配置对某个 kernel 进行特殊采集、管理对比基准。作者的报告还用不到这些比较高级的功能;
  • Tools 是各类工具窗口和软件设置的入口,默认配置就好;
  • Window 管理界面里各个 Tool Windows 的布局。Tool Windows 就是 Main Menu 下方工作区里那些可以拖动、调整停靠位置的面板。Window 里面有保存和恢复窗口布局的功能,各个面板调整到符合个人习惯后把布局保存一下,之后万一拖乱了能一键恢复;
  • Help 查看软件版本信息、打开官方文档。

Main Menu 下面那排按钮是 Main Toolbar。它其实就是把 Main Menu 里一系列高频动作又做成一个快捷按钮,基本都属于实时采集和现场调试的入口,这一排现在一个都用不上。

再往下,左边 Project Explorer 是项目管理器,打开报告的时候工程已经自动建好了,不必过多关注;右边 Documents,就是之后真正主要关注的部分。

Documents 页面

报告头

报告打开后,Documents 最顶部已经显示打开了 reduce-ill.ncu-rep,再下方是 kernel 的基本运行信息:

报告头特写

报告只针对一个 kernel 且只采集了一次,所以这份报告自始至终只有一条结果,会使很多筛选和对比性质的功能都无效,但这样也能更好地突出重点。从左往右看:

项 值 含义
勾选框(方块) 已勾选(方块涂为实心蓝色) 在多结果的场景中,选中某个结果做表头汇总、结果导出、对比基准这类操作。对于本报告就无作用了
Current Result 552 - reduce_ill 一个报告里可以有多条采集结果,这个下拉框用来切换当前看哪条。对于本报告,没什么可切的。
ncu 拿"调用编号 + kernel 名"命名。这里 552 是 API Call ID,是指这条 kernel 是采集期间 CPU 发起的第 552 次 CUDA API 调用
筛选按钮(小沙漏) 空 按条件过滤结果列表,高级功能。对于本报告,没什么好筛选的,也无作用了
Size (8192, 1, 1)x(256, 1, 1) kernel 的 grid 的三维大小和 block 的三维大小
Time 318.43 us kernel 的执行时间,以 us 为单位
Cycles 443,927 kernel 的执行时间,以 GPU 周期为单位
GPU 0 – NVIDIA GeForce RTX 3090 kernel 的运行所在显卡
SM Frequency 1.39 GHz 显卡上各 SM 的实际平均频率
SM Frequency = Cycles / Time
Process [389058] reduce 采集时目标进程的 PID 和名字
Attributes 齿轮图标 点一下会跳到 Details 页的 Launch Statistics,是更详细的启动 kernel 时的配置信息,先只了解一下

报告主体

再往下的一排标签就是报告的七个页面:Summary、Details、Source、Context、Comments、Raw、Session,整个合集的主线就围绕它们推进:

  • Summary 是采集结果的一览表,双击某一条数据就会跳到对应的 Details,界面最下方是 ncu 官方给出的优化建议,按预计的加速空间从高到低排;
  • Details 是所有指标数据的大合集,采到的东西全在这页,被切成一个个 section,ncu 内置一套分析规则,得出的警告也挂在各自 section 头上,这是信息量巨大的一页,是之后的重点;
  • Source 把 GPU 的汇编码 SASS 和 CUDA-C 源码对照起来,把指标挂到每条指令、每行源码上,指出硬件计数器翻译回代码对应哪一行,也是之后的重点;
  • Context 记录采集期间的 CPU 调用栈和 NVTX 状态;
  • Comments 用来给报告和各 section 写备注;
  • Raw 是全部指标的原始账本,记录所有采集到信息的原始值和单位,带 filter 框能按名字筛;
  • Session 记录这次采集的环境情况,包括命令行怎么启动的采集、采集主机和目标设备的属性信息。

标签栏右边还有 Compare、Tools、View、Export 和一个三条横线的小按钮,分别管对比基准、附属工具、视图切换和导出。最后那个小按钮是关于规则应用的选项。这几个按钮里最常用的就是 Export,其它的先不展开。

Summary 页面

数据列表

再往下就是本页的主角,Summary 页面,左上角的两个箭头围成圈的按钮是转置数据表格。

summary信息

各指标具体如下:

项 值 含义
ID 0 这条结果在报告里的编号
Estimated Speedup [%] 86.10 ncu 的规则引擎估计的优化空间上限,意思是"按它的建议改,理论上最多能快这么多"
Function Name reduce_ill kernel 名字
Demangled Name reduce_ill(float *, float *, int) kernel 名反修饰还原出的 C++ 完整签名函数名
Duration [us] 318.43 kernel 的执行时间
Runtime Improvement [us] 274.16 按 ncu 建议改完后理论上能省下的执行时间,是 ncu 拿 Duration 乘上 Estimated Speedup 算出来的
Compute Throughput [%] 15.98 计算侧利用率
Memory Throughput [%] 80.44 内存侧利用率
# Registers 36 每个线程用了 36 个寄存器
Grid Size 8192, 1, 1 grid 三维大小
Block Size 256, 1, 1 block 三维大小

我们重点关注:

  • Duration,执行时间,硬件计时器测的,只算 kernel 真正在 GPU 上跑的那段时间,启动和数据搬运这些开销都不掺在里面,我们做完算子优化后,比较它就可以知道是不是快了,快了多少。
  • Compute Throughput,计算侧利用率,算法是把 SM 里各条计算管线,整数、浮点、访存指令这些各自的实际吞吐除以各自的理论峰值,再取其中的最高者。这个值越高,代表计算单元越逼近自己的算力极限,本报告只有 15.98%,说明算力大量闲置,优化的空间不在这里。
  • Memory Throughput,内存侧利用率,算法是从 L1TEX 到 L2 再到显存这条链路上各通路的实际吞吐除以各自的理论峰值,再取其中的最高者。这个值越高,代表访存侧越逼近自己的带宽极限,80.44% 属于较高的范畴了,说明数据搬运非常繁忙,再配合 Compute Throughput 的低值,我们就可以读出这个 kernel 的问题出在内存侧,计算单元大部分时间都在干等数据搬运到位,所以优化空间就是怎么优化数据的搬运链路,尽量减少计算单元可以计算但数据没送到而不得不干等的时间。

ncu 优化建议

表格下面还有一块区域,列着 ncu 给出的优化建议,叫 Prioritized Rules,按预计加速比从高到低排序。每条建议最左边是规则名,指出当前的数据触发了 ncu 建议库中的哪一条,其下方是 ncu 的判断预计加速比,意为如果按这条建议把问题优化好了,理论上预计能提升这么多。右侧具体描述问题是什么,最右侧有个小圆圈箭头,点开会展开和这条建议强相关的指标数据。作者这份报告 ncu 给出了三条建议:

官方建议

  • Uncoalesced Global Accesses,未合并的全局访问,预计加速 86.10%,说这个 kernel 存在未合并的全局访存,一共多产生了 14,680,064 个 sector,占全部 16,785,408 个 sector 的 87%;更多信息可以去 L2 Theoretical Sectors Global Excessive 表找这些多余 sector 主要出在哪些代码位置。这个反映的正是序章中的病态一,当时算过病态一把从显存取数的读流量放大了 8 倍,8 份流量里 7 份白搬,如果内存是合并访问,硬件就不用额外多搬近 1468 万个 sector,7/8 = 87.5%,正对应了此处 ncu 指出来的 87%。点开圆圈箭头,展开的正是官方说明里指的那张 L2 Theoretical Sectors Global Excessive 表,它记录了实际采到的 sector 数减去理想情况下装下同样有效字节所需的最少 sector 数,即白搬的次数,给出的建议也很明确,减少 L2 缓存中多余的 Wavefronts 数量,和优化为内存合并访问一个意思。
  • L1TEX Global Load Access Pattern,L1TEX 全局加载访问模式不佳,预计加速 80.90%,说 L1TEX 的全局加载访存模式可能不是最优的,平均每个 sector 传输的 32 字节里,每个线程只利用了 4.0 字节,这可能是由线程间的地址间隔造成的;更多信息可以去 Source Counters 部分查未合并的全局加载。这个和第一条是同一个问题,只是视角不同,第一条从 L2 的 sector 流量算总账,这条从 L1TEX 的字节利用率找原因。序章中也算过,一个 warp 每个 thread 只用 4 字节、硬件却必须搬 32 字节,"每个线程只用 4 字节"正是该建议的直接写照。点开圆圈箭头,展开的表格就两行:第一行是 Bytes per Sector 4.0,指出的就是这个现状,给出的建议是把每个 sector 平均用到的字节数往 32 字节上提;第二行是 L1TEX 的吞吐 92.45%,想说的是 L1TEX 越忙,这个问题就越严重。所以本条建议本质上和上一条是一个意思。
  • L1TEX Global Store Access Pattern,L1TEX 全局存储访问模式不佳,预计加速 80.90%,说的和上一条几乎一字不差,只是把加载换成了存储,展开的表格都完全一样,其本质上也和上一条一个意思。

这一章到这里就结束了,现在我们已经能看懂报告的首页,并且能粗略地定位问题在哪里了,但要具体的找出问题具体藏在链路的哪一级、代码的哪一行,还得去 Details 页里翻。下一章我们就来重点关注 Details 页面的核心数据。

posted @ 2026-09-26 17:08  _nibel  阅读(5)  评论(0)    收藏  举报