你是一家超级工厂的厂长。工厂里有八千名工人,每 32 人编成一个小队,动作整齐划一,像军队方阵一样齐步走。设备是崭新的 GPU——但你总觉得产量不对劲:设计指标是每秒处理一百万个订单,实际却只有六十万。你没法钻进车间挨个询问工人为何拖延,你需要一套“监控系统”。 这套系统就是 CUDA Profile 工具。它分两层:Nsight Systems 像是厂区上空的 CCTV,回放整天的生产画面,看哪条流水线在空转;Nsight Compute 则像质检员手里的显微镜,对准单个工位,记录工人每一次停顿的真实原因。在这套系统帮助下,你能从“猜性能”变成“测性能”,精准定位瓶颈,用数据驱动优化。
掌握 CUDA 性能分析工具,你将摆脱“凭感觉调优”,学会用数据定位 GPU 程序瓶颈,这是每位 AI 基础设施工程师和高性能计算工程师的核心竞争力。
目录
可视化演示
\u5c55\u793a\u5ba2\u6237\u7aef\u5411NameNode\u8bf7\u6c42\u5199\u5165\uff0c\u83b7\u53d6DataNode\u5217\u8868\u540e\u5efa\u7acb\u6570\u636e\u7ba1\u9053\uff0c\u6570\u636e\u5305\u7ecf\u7531\u4e09\u4e2aDataNode\u4e32\u8054\u590d\u5236\u5e76\u9010\u7ea7\u786e\u8ba4\u7684\u5168\u8fc7\u7a0b\u3002
本节配有交互动效(进入视口后自动加载,约 3KB)。
HDFS\u5199\u5165\u6d41\u7a0b \u5ba2\u6237\u7aef\u53d1\u8d77\u5199\u8bf7\u6c42 \u5f53\u524d\u6570\u636e\u6d41 Rep=3 \u4e09\u526f\u672c\u4e32\u8054\u590d\u5236
性能分析总览:先装监控,再谈改造
厂长请来一位资深生产顾问。顾问没有急着换机器,而是带团队在厂区安装了几十台监控摄像头和流量计。他说:“不先搞清楚生产线哪里堵、哪里空转,花再多钱改造都是瞎猜。”性能分析也是同一个道理:GPU 程序跑得慢,直接改代码就像蒙眼修机器,先测量、再定位,才知道刀该往哪里落。
在 CUDA 开发中,性能分析(Profiling)是一个系统性的“侦查”过程:先用工具收集程序运行的各项指标——kernel 耗时、内存数据传输量、SM 利用率等,再对比理论极限,找出最拖累性能的环节。常用分析工具分两个层级:Nsight Systems 负责“全局侦查”,看整个应用的时间线;Nsight Compute 负责“定点侦查”,把单个 kernel 放大到指令级分析。两者配合,从面到点逐步逼近问题核心。
Amdahl 定律则指出了优化的理论天花板:程序整体加速比的上限,取决于代码中可并行部分的比例。哪怕有 100 个处理器,如果 90% 的代码只能串行执行,最终加速也不会超过 10 倍。所以分析的第一步,往往要先弄清“串行部分”到底有多大。
回到工厂,顾问装好监控后统计“有多少工人其实不能同时开工”。如果某道工序必须排队串行,那就算买再多的 GPU 也无济于事。性能分析的价值,就是把这种“串行死角”从黑箱中揪出来。
- 可并行占比 P把总工作量视为 1,其中可并行执行的部分比例记为 \(P\)。比如一个任务 70% 可以被多个工人同时做,则 \(P=0.7\)。
- 串行拖尾 1-P剩下 \(1-P\) 无法并行,无论多少处理器都只能顺序执行,是整个加速过程的天花板。
- 并行耗时把可并行部分平分到 \(N\) 个处理器上,耗时变为原来的 \(P/N\)。
- 总加速比原始总时间除以新总时间,得到理论最大加速比。
Nsight Systems:全厂 CCTV 回放
安装好监控后,顾问把一整天的生产录像导入控制台。屏幕上是一条横贯的时间轴:绿色色块是生产线在运转,灰色色块是传送带空转,蓝色块是原材料进场的时间。一眼就能看出:生产线启动间隙里,传送带经常空着,CPU 在发呆,整个流程是“干一会儿,停一会儿”。
Nsight Systems 就是 GPU 世界的“全厂 CCTV”。它记录整个应用的执行时间线:CPU 端函数调用、GPU kernel 的开始与结束、Host 与 Device 之间的数据拷贝。它的强项不是看某个 kernel 内部细节,而是看“全局节奏”——kernel 之间有没有空隙、数据拷贝是否与计算重叠、CPU 是否在等待 GPU。这些信息来自显卡驱动与 CUDA 运行时的时间戳回放,对程序几乎没有侵入。
很多 CUDA 程序性能差的根源不在单个 kernel 太慢,而在 kernel 之间“空转”太多。例如 CPU 要等 D2H 拷贝完成,才启动下一个同样需要读 GPU 内存的 kernel——全局时间线上一目了然。把总时间按阶段拆开,你会惊讶地发现“真正计算”的时间占比往往不到一半。
回到工厂:老板发现流水线“停一段、跑一段”,问题不在车间本身,而在车间之间的衔接。用 Nsight Systems 看到全局时间线后,优化目标就变成了“让传送带 24 小时不停”,这正是异步拷贝与多流(Stream)设计要解决的事。
- 计算时间kernel 真正在 GPU 计算单元上执行的总时长。
- 传输时间Host 与 Device 之间数据拷贝占用的时长。
- 空闲时间CPU 等待 GPU、GPU 等待数据或同步导致的空白时间。
- 总时间求和三者相加即应用程序端到端的执行时间。
Nsight Compute:质检员上门查细节
CCTV 锁定“3 号车间最慢”后,顾问带着显微镜走进车间,对准某个工位观察:工人每做一次动作,要等多久才能拿到下一个零件?手边工具有没有备齐?同一时刻工位上到底几个人在干活?Nsight Compute 扮演的正是这个“定点质检员”角色,专门针对单个 kernel 做毫米级体检。
与 Nsight Systems 看全局不同,Nsight Compute 只聚焦一个 kernel,输出该 kernel 内部的执行细节:SM 利用率、指令吞吐、内存吞吐、每条指令的 stall 原因,甚至直接映射到源码的某一行。它通过 GPU 内置的性能计数器采集数据,并在报告里用“红黄绿”标注问题区域,帮助开发者快速区分“算不动”和“等不到”。
使用 Nsight Compute 通常分三步:先在 Nsight Systems 中确定最耗时的 kernel;然后用 Nsight Compute 默认 Profile 集运行,拿到吞吐率、占用率、瓶颈类型等核心指标;最后顺着 stall 统计定位到具体代码行,查看原因与指令混排情况。这也是官方推荐的“从全局到局部”的分析路径。
质检员放下显微镜,在报告单上写下:3 号车间只有一半工位有人,其余工位因为缺少“零件”(数据)而空转。这个结论将直接引导下一步:去看数据没到的原因——也就是内存带宽问题。
- 活跃 SM 数统计内核执行期间实际参与计算的流多处理器(SM)数量。
- SM 总数GPU 上配置的物理 SM 总个数,例如 A100 有 108 个 SM。
- 利用率比值活跃数除以总数得到 SM 利用率,越接近 1 说明硬件越“忙”。
Kernel 指标:车间产量报表
质检报告记录着每个内核的“产量报表”:执行时长、从启动到结束的周期数、执行了多少指令、计算指令与访存指令占比等。这些指标共同描绘出一个内核的真实健康状态。拿到报表后,第一件事不是看哪个数字最大,而是判断瓶颈到底属于哪一类。
两个指标最值得关注。第一个是内核执行时间(Kernel Duration),它是 GPU 任务中最直观的“耗时大头”;第二个是指令吞吐率,通常用 IPC(每周期执行的指令数)衡量。IPC 越高,说明 GPU 的运算单元“越忙”。如果 IPC 很低,即使内核很长,问题也可能出在“空闲”而非“计算量大”。
有了这些指标,就可以给内核分类:计算密集型(指令吞吐高、内存吞吐低)、访存密集型(内存吞吐接近峰值)、延迟密集型(大量 stall、SM 利用率低)。优化手段完全不同:计算密集要优化算法或指令流水;访存密集要改进合并访问;延迟密集要提高 Occupancy,通过更多并发掩盖等待。
报表出来了,车间主任发现:产量低不是因为工人动作慢,而是因为“半成品堆不进工位”导致大家都在干等——这是典型的访存密集信号。下一步,顾问把注意力转向传送带的宽度。
- 指令总数kernel 执行过程中发射的指令条数。
- 周期总数kernel 从开始到结束经历的核心时钟周期数。
- 相除得 IPC指令数除以周期数表示平均每周期执行指令数。
内存带宽:传送带不够宽
走进 3 号车间,顾问发现几十个工位同时在等“原材料”。传送带明明在高速运转,可送上来的物料远不够喂饱所有人。原因很清楚:传送带(内存总线)太窄,单位时间能送到的数据只有那么多。GPU 计算动辄每秒数 TB 的吞吐需求,而显存带宽往往成了第一个瓶颈。
内存带宽分析的思路很简单:先算“实际带宽”,再和“理论峰值”做比较。实际带宽 = 内核执行期间实际从显存读写的数据量 ÷ 执行时间;理论峰值则取决于显存频率与位宽,由硬件规格决定。当带宽利用率持续超过 80%,基本可以判定内核已经被访存“喂不饱”了。
另一个关键点是“合并访问”(Coalesced Access):同一 warp 的 32 个线程访问内存时,如果地址连续,硬件可以合并成一次“大卡车运输”;如果地址跳来跳去,就退化成多次“小轿车运输”,有效带宽大打折扣。Nsight Compute 的 Memory Workload Analysis 面板会直接显示每个 load/store 指令的合并效率,是优化访存模式的重要依据。
传送带加宽之前,先看看物料是不是“捆成了整齐的集装箱”。如果同一小组的工人请求的物料地址是连续的,一次就能拉回来一整车——这就是合并访问的精髓。
- 传输数据量内核执行期间 GPU 从显存读取和写回的总字节数。
- 执行时间内核执行持续的时间,取秒为单位。
- 实际带宽数据量除以时间得到实际带宽。
- 与理论峰值对比实际带宽除以显存理论带宽,得到带宽效率。
Warp 停顿:工人为何齐刷刷停下
GPU 里的工人并不单独行动——每 32 个线程组成一个 warp,像 32 人齐步走的乐队方阵。调度器每次只调度整个 warp,而不是某个线程。只要方阵里有一名队员需要等待数据,整个方阵都得停下来。这种“停下等待”就叫 warp stall。
Nsight Compute 会告诉我们每个 warp 停下来的原因:等待全局内存返回数据(最典型)、等待共享内存、指令依赖(上一条算完下一条才能算)、还有同步屏障(barrier)。这些 stall 信息精确到指令行,是定位延迟问题的“X 光片”。通过 Warp State 面板,开发者可以按 stall 原因排序,看到哪个原因耗时最多。
停工不可怕,可怕的是停工期间无人代替干活。GPU 隐藏内存延迟的秘诀是“人多”:如果 SM 里同时驻留足够多的 warp,一个 warp 停下时调度器立刻切换到另一个能跑的 warp,计算单元就不会闲下来。反过来,warp 数量不够时,stall 会直接暴露为空白周期,表现为 IPC 和 SM 利用率双低。
想让乐队不冷场,最简单的方法就是多安排几支乐队轮番上阵。GPU 里的“乐队数量”就是下一个概念——Occupancy,即 SM 能同时容纳多少个 warp。
- 内存等待延迟一次内存访问从发出到数据返回的等待周期数。
- 指令发射率每个周期 SM 发射指令的速率,通常为每秒数个指令。
- 所需并发 warp 数两者相乘得到为了藏住延迟至少需要同时就绪的 warp 数。
Occupancy:车间的容量极限
车间面积(SM 资源)是有限的,能同时容纳的 warp 数量有上限。比如一个典型的 SM 最多容纳 64 个 warp。但实际能住进多少支“乐队”,取决于每支乐队占了多少资源——寄存器数量、共享内存大小、线程块大小都会化作“占地面积”。
Occupancy 的定义很直接:实际活跃 warp 数 ÷ SM 能容纳的最大 warp 数。比如 SM 最多 64 个 warp,当前只有 32 个活跃,Occupancy 就是 50%。Nsight Compute 会同时显示理论 Occupancy 和实测 Occupancy,两者差异往往来自寄存器溢出、资源分配不均或线程块调度限制。
提高 Occupancy 的常见手段包括:通过 __launch_bounds__ 或编译器参数限制每线程寄存器用量、调整线程块大小来匹配 SM 资源、减少每块共享内存的消耗。但要注意:Occupancy 不是越高越好。过高的 Occupancy 会压缩每线程资源,可能让指令级效率下降,所以要在“并发度”和“单线程资源”之间寻找平衡点。
车间里座位太少,原材料一到货没人腾手搬运;座位太多,每个人分到的工具箱又不够用。找到那个临界点,就是 Occupancy 优化的艺术。
- 活跃 warp 数内核执行时平均在 SM 上同时驻留的 warp 数。
- 最大 warp 容量SM 硬件设计上能容纳的 warp 上限,常见值为 32 或 64。
- 相除得占用率活跃数除以容量得到 Occupancy 百分比。
优化实践:让数据说话
现在老板手里已经有三份报告:全局时间线(Nsight Systems)、内核放大镜(Nsight Compute)、指标报表(Kernel 指标)。该怎么动手?实践顺序是:先读全局报告确定最耗时的 kernel,再用 Compute 报告判断瓶颈类型(计算/带宽/延迟),然后按“投入产出比”排序——通常先修带宽,再调 Occupancy,最后才去折腾指令级细节。
每一轮优化结束,必须重新跑一遍 Profile 工具验证效果。优化前的执行时间记为 \(T_{before}\),优化后记为 \(T_{after}\),加速比为两者之比。如果加速比接近 1,说明真正的瓶颈还没被击中——这时瓶颈可能已经转移,要回到第一步重新分析。
一个经典案例:矩阵乘法 kernel 的原始实现中,每个线程按行读取矩阵 A 的同一列元素,访存完全不连续,带宽效率只有 12%。改用共享内存分块 + 连续访问后,带宽效率提升到 75%,kernel 执行时间从 4.2ms 降至 1.1ms——加速比 3.8 倍。整个过程没改算法,只是让数据流动方式更符合硬件特性。
监控系统装好了,数据也测透了,老板恍然大悟:所谓“慢工厂”其实只是传送带太窄、乐队太少。每一次改动后重新打开监控回放,看到新的瓶颈点被点亮——这就是 Profile 驱动的优化循环:测、判、改、再测。
- 优化前耗时执行第一次 Profile 时的内核执行时间。
- 优化后耗时完成一轮改动后重新测量得到的执行时间。
- 加速比两者相除,度量优化带来的收益倍数。
AI 应用场景
场景1:自动驾驶感知模型推理性能优化
阶段:模型推理部署与性能调优
解决的问题:自动驾驶的感知模型在 GPU 上运行时,传统秒表式计时只能看到端到端延迟很高,却说不清延迟消耗在数据读取、前处理、GPU kernel 还是后处理。用 Nsight Systems 可以看到每个阶段的时间占比,不再猜测。
具体案例:某自动驾驶团队用 TensorRT 部署目标检测模型,端到端延迟 35ms,达不到 30ms 的指标。通过 Nsight Systems 全局时间线发现,主机与设备之间的图像传输占用 18ms 且与 kernel 完全串行。改为异步传输 + 多流重叠后,延迟降到 19ms,成功落地。
场景2:大模型训练数据管道“饿肚子”
阶段:训练数据加载管道优化
解决的问题:大模型训练时 GPU 算力常被闲置,不是因为 kernel 慢,而是数据加载管道太慢,GPU 饿着肚子等饭。传统指标只能看到 GPU 利用率低,无法定位是哪一段管道阻塞。
具体案例:训练类 GPT 模型时,Nsight Systems 展示 GPU kernel 之间的大片空白——GPU 利用率仅 42%。定位为 CPU 侧数据预处理(tokenizer、shuffle)耗时,跟不上 GPU 消费速度。通过多进程 DataLoader、CUDA 内存池与预取策略,GPU 利用率提升到 85% 以上。
场景3:科学计算仿真内核的 Occupancy 拯救计划
阶段:HPC 核心计算模块分析
解决的问题:流体仿真程序在 GPU 上跑得慢,开发人员一度以为“算力不够”要换卡。Nsight Compute 显示 kernel 的 Occupancy 只有 25%,因为每个线程用了 128 个寄存器,导致活跃 warp 严重不足。
具体案例:某科研组用 CUDA 做 LBM 流体模拟,通过 Nsight Compute 看到 warp stall 大量源于寄存器压力过高。通过限制寄存器数为 64 并重组数据布局,Occupancy 从 25% 提升到 62%,模拟速度提升 1.9 倍,避免了几十万元的硬件升级费用。
Python 演示
"""GPU Kernel 性能分析模拟器用纯 Python 演示 Profile 工具的核心计算逻辑:内存带宽、IPC、Occupancy 与瓶颈诊断""" class KernelProfile: def __init__(self, name, instr_count, cycles, bytes_moved, active_warps, max_warps=64): self.name = name self.instr = instr_count self.cycles = cycles self.bytes_moved = bytes_moved self.active_warps = active_warps self.max_warps = max_warps def ipc(self): return self.instr / self.cycles def bandwidth(self, clock_hz): time_sec = self.cycles / clock_hz return self.bytes_moved / time_sec def occupancy(self): return self.active_warps / self.max_warps def diagnose(self, device_bw, clock_hz): bw_ratio = self.bandwidth(clock_hz) / device_bw occ = self.occupancy() print(f"[{self.name}] IPC={self.ipc():.2f} " f"带宽利用率={bw_ratio:.1%} Occupancy={occ:.0%}") if bw_ratio > 0.8: return "结论:内存带宽瓶颈,应优化合并访问策略" if occ < 0.5: return "结论:延迟隐藏不足,需提高 Occupancy" return "结论:计算密度良好,可尝试指令级优化" if __name__ == "__main__": kernels = [ KernelProfile("matmul_v1", 50_000_000, 20_000_000, 10_000_000_000, 32), KernelProfile("matmul_v2", 80_000_000, 8_000_000, 2_000_000_000, 48), ] for k in kernels: print(k.diagnose(device_bw=900e9, clock_hz=1.5e9))
time_sec = self.cycles / clock_hz把 GPU 时钟周期换算成秒,这是后续所有带宽计算的基础。return self.bytes_moved / time_sec计算实际带宽,对应 Nsight Compute 的 Memory Throughput 指标。bw_ratio = self.bandwidth(clock_hz) / device_bw计算带宽利用率,超过 80% 就判定带宽瓶颈。return self.active_warps / self.max_warps核心的 Occupancy 计算,活跃 warp 数除以 SM 容量。if occ < 0.5:低于 50% 说明延迟隐藏能力不足,优先提升 Occupancy 而不是优化指令。
常见误区
误区用 Nsight Compute 一看到 Occupancy 低于 80% 就紧张,想方设法把 Occupancy 拉满,以为数值越高性能就越好。
正解Occupancy 的本质是“可隐藏延迟的 warp 数量”,并非性能的终点评判。开太高时,每线程寄存器被压缩、共享内存变小,甚至产生寄存器溢出,反而降低指令执行效率。真实的最优 Occupancy 取决于 kernel 属性和瓶颈类型,需要实测对比,不能只看百分比。
为何常见:百分比天然给人“越大越好”的直觉,加上教程里经常强调“低 Occupancy 会导致瓶颈”,新手很容易把手段当成目的。
误区“为什么 Profile 之后我的 kernel 从 3ms 变成 30ms?这个工具是不是有问题?”很多初学者一看到 profiling 前后的时间差就怀疑工具。
正解Profiling 需要 GPU 内置计数器记录指令级事件,这会打断正常流水并注入额外记录开销。Profile 开的是“化验模式”,不代表代码真实执行速度。关键是读相对指标,而不是把 profiling 状态下的时间当成线上执行时间。
为何常见:把测量过程的开销误当成了程序本身的运行开销。就像上跑步机测体能,身上绑了心率带,数据自然会和裸跑不一样。
误区看到 Memory Throughput 接近 90% 就断定“这 kernel 是访存瓶颈,无需再看其他指标”。
正解高带宽利用率只是“内存瓶颈”的充分条件之一,还要结合 stall 原因判断是不是因为合并访问不佳导致请求数量过多。如果 warp 大量 stall 在等待内存而 Occupancy 又低,即使带宽没到 90%,也依然是访存问题。交叉验证比单指标下结论更可靠。
为何常见:单一指标容易读,且工具默认高亮红色警告,初学者容易把最醒目的数据当结论。
误区优化后 Nsight Compute 显示 kernel 执行时间少了 30%,立刻宣布优化成功。
正解kernel 时间只是全局流程的一部分。Nsight Systems 全局时间线上,数据传输、CPU 启动开销和同步等待往往占大头。数据拷贝时间甚至可能因为布局调整而增加。必须从端到端重新测量,确认总时间确实下降,才算真正成功。
为何常见:GPU 从业者习惯聚焦 kernel 耗时,忽略了“数据搬运和调度”同样吃时间,这在以 PCIe 传输为主的场景尤其常见。
面试题
Q1. Nsight Systems 的主要作用是?
- A.查看应用全局时间线和数据流← 正确答案
- B.查看内核内部指令流水细节
- C.自动改写 CUDA 内核代码
- D.调整 GPU 核心频率设置
答案:A。Nsight Systems 负责全局时间线,像工厂 CCTV 俯瞰全场;Nsight Compute 才是内核级放大镜。C 是编译器的工作,D 与性能分析工具无关。
Q2. SM 可容纳最大 warp 为 64,当前活跃 32 个,Occupancy 是多少?
- A.25%
- B.50%← 正确答案
- C.75%
- D.100%
答案:B。Occupancy = 活跃 warp 数 ÷ 最大 warp 数 = 32 ÷ 64 = 50%。好比 64 个工位只坐了 32 人,车间有一半是空的。
Q3. 关于合并访问,正确的说法是?
- A.连续地址访问便于合并为一次事务← 正确答案
- B.随机地址访问可以提高总线速度
- C.只有共享内存才会发生合并访问
- D.合并访问对访存性能没有影响
答案:A。同一 warp 的 32 个线程访问连续地址时,硬件能合并成少数缓存行事务一次交付,如同把零散货物装进一辆大卡车。随机地址会碎片化,有效带宽大幅下降。
Q4. Warp stall 指的是什么?
- A.整个 GPU 时钟频率自动下降
- B.warp 等待数据或资源而暂停← 正确答案
- C.kernel 执行时间超过预期上限
- D.显存容量耗尽导致的错误退出
答案:B。Warp stall 是 warp 因等待内存返回、指令依赖或同步等原因无法发射指令的现象。它不是频率调节,也不是异常退出,而是正常的调度等待状态。
Q5. 带宽利用率 95% 但 Occupancy 仅 30%,优先做什么?
- A.立刻增加线程数提升 Occupancy
- B.直接减少寄存器用量继续优化
- C.交叉验证访存与占用双重瓶颈← 正确答案
- D.放弃 Profile 直接换更大的显存
答案:C。两个指标同时异常时不能只修一个:带宽高说明是访存密集型,Occupancy 低说明延迟隐藏差。需要同时考虑合并访问优化和资源分配调整,才能让优化真正生效。
Q6. 寄存器用量过高的直接后果是?
- A.降低 SM 驻留 warp 数量上限← 正确答案
- B.提升全局内存有效可用带宽
- C.显著加快单线程执行速度
- D.使指令缓存命中率大幅上升
答案:A。寄存器是 SM 内的稀缺资源,每个线程占得多,SM 能容纳的 warp 就少,Occupancy 随之下降,延迟隐藏能力变差。其他选项都不是寄存器增多的直接后果。
Q7. Nsight Systems 显示数据拷贝与计算完全串行,应如何优化?
- A.去掉数据拷贝让 GPU 直接读主机内存
- B.使用异步拷贝让传输与计算重叠← 正确答案
- C.换成更大容量但更慢的显存
- D.减少内核次数保持当前串行结构
答案:B。完全串行的拷贝与计算之间有空隙,使用异步传输与多流技术可以让数据搬运和计算同时进行,把空闲时间利用起来。其他选项要么不可行,要么不能解决串行问题。
Q8. 哪些属于 CUDA Profile 常用工具?
- A.Nsight Systems 全局分析器← 正确答案
- B.Nsight Compute 内核分析器← 正确答案
- C.操作系统自带的任务管理器
- D.文本编辑器 Vim 的插件市场
答案:AB。Nsight Systems 与 Nsight Compute 是 CUDA 官方两大分析工具。任务管理器只能看到 GPU 整体占用,插件市场与性能分析无关。
Q9. 哪些资源限制会降低最大 Occupancy?
- A.寄存器文件容量有限← 正确答案
- B.共享内存容量有限← 正确答案
- C.块数量上限有限← 正确答案
- D.全局内存容量无限扩展
答案:ABC。寄存器、共享内存、线程块数量都是 SM 驻留 warp 数的限制因素,任何一个资源耗尽都会减少可容纳的 warp。全局内存容量不影响 Occupancy。
Q10. 解读 Nsight Compute 报告时,正确做法是?
- A.结合吞吐率与延迟共同判断← 正确答案
- B.只相信最先看到的红色指标
- C.查看 stall 原因定位到代码行← 正确答案
- D.对比多次优化后的指标变化← 正确答案
答案:ACD。性能分析要综合多维度数据,红色警示只是入口,stall 原因能精确定位代码行,多次指标对比才能验证优化效果。只盯单一红色指标容易误判瓶颈方向。