想象你是一家“全自动餐厅”的老板。后厨里有一百位普通厨师(CUDA 核心)守着各自的炉灶,大厅中央摆着一座魔法蒸锅(Tensor Core)——只要食材按 4×4 的方阵摆好,它一次能同时蒸熟几十道菜。最近餐厅出菜越来越慢,客人在催单。你凭直觉想“再买一口更大的锅”,但真正的问题可能根本不在锅:也许是传菜员(内存带宽)从仓库搬食材太慢,也许是厨师们在蒸锅前干等(停滞 stall),也许是洗、切、炒三个工位之间反复装箱入库(访存开销)浪费了时间。 一位效率顾问(Nsight Compute 等性能分析工具)在后厨装了一圈监控探头,记录每位厨师每一秒在干什么:锅开了多久、人等了几秒、食材在仓库与灶台之间走了几趟;再画一张“餐厅瓶颈速查表”(Roofline 模型)区分“锅的产能”与“上菜速度”谁在卡脖子;最后给出改造方案:把三个工位合并成一条流水线(算子融合),让食材不再落地。本文就带你走完这套“厨房效率大作战”的全流程。

岗位关联

掌握 Tensor Core 性能分析,你就能用数据说话:一眼定位 AI 算子的真实瓶颈,让每一次优化都精准命中。这是 GPU 性能工程师、训练优化工程师最硬核的看家本领。

目录
  1. 可视化演示
  2. 性能分析概览
  3. 核心利用率
  4. 内存带宽分析
  5. Roofline模型
  6. 停滞原因诊断
  7. 算子融合优化
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态展示利用率指标、Roofline模型、Stall原因诊断与优化迭代流程四个视角,直观理解Nsight Compute性能分析工作流。

本节配有交互动效(进入视口后自动加载,约 3KB)。

性能分析概览

老板安装监控后的第一件事,不是忙着下令改造,而是先把营业时间里的每一分钟都录下来,按“备菜、蒸制、上桌”切成片段回放。性能分析的起点同样如此:先用工具把 GPU 上发生的每一类活动记录下来,再回答一个朴素的问题——时间到底花在了哪里。

这个“厨房监控”就是 Nsight Compute。它工作在指令级别:对于一个 CUDA 内核,它报告哪些指令流水线在忙碌、哪些 warp 在等待、各级缓存与显存搬运了多少数据。和 nvidia-smi 只能看到整卡负载不同,Nsight Compute 把内核执行的每一拍都摊开在桌面上,是 Tensor Core 性能分析的主角工具。

完整的工作流通常有五步:采集(用 Nsight Compute 抓取热点内核)、归类(把时间按计算、访存、等待拆分)、定位(沿着指标树下钻到具体指令与停滞理由)、优化(实施针对性改造)、验证(复测并对比基线)。而这一切的前提,是先建立“总时间等于各内核时间之和”的分解意识。

就像老板先看哪一段工序耗时最长,分析者先把总时长拆到每个内核,才能锁定要深挖的目标——接下来的每一节,都在回答“拆开之后怎么看”。

Ttotal=∑i=1nTkerneliT_{\text{total}} = \sum_{i=1}^{n} T_{\text{kernel}_i}
总执行时间可以拆成所有内核执行时间的累加,这是所有占比型指标的“分母基准”。
  1. 总执行时间 T_total整个算子或应用在 GPU 上消耗的总时长,后续所有利用率计算都以它为分母。
    TtotalT_{\text{total}}
  2. 求和符号 Σ表示把从第 1 个到第 n 个内核的执行时间逐项累加起来。
    ∑i=1n\sum_{i=1}^{n}
  3. 第 i 个内核时间一个深度学习算子往往被拆成多个 kernel,每个内核的耗时各占一份。
    TkerneliT_{\text{kernel}_i}

核心利用率

监控回放里,老板最关心那口魔法蒸锅:一整天下来,锅盖真正被蒸汽顶起的时间有多少?这个比例,就是 Tensor Core 利用率。锅虽然先进,但如果一天 8 小时只有 1.6 小时在冒热气,那再大的锅也等于摆设。

在 Nsight Compute 中,通过 Tensor 流水线的活跃周期计数,可以算出 Tensor Core 利用率:Tensor Core 忙碌时间除以内核总执行时间。它回答的是“计算单元在总时长中的忙碌占比”,而不是“计算能力有多强”。利用率低不代表硬件弱,只代表它没被喂饱。

利用率低通常有三类病根:一是算子形状与 tile 不匹配,矩阵数据喂不进 Tensor Core 的乘加阵列;二是访存供给不足,Tensor Core 在空转等待数据;三是占用率过低,活跃 warp 太少,无法用并行掩盖延迟。三种病因对应的药方完全不同——改布局、提带宽、调占用。

老板发现蒸锅睡着后,先要分辨是“没菜可蒸”还是“菜在路上堵着”。前者去看算子形态,后者把镜头对准传菜员——也就是下一节的内存带宽。

UTC=TTCTtotal×100%U_{\text{TC}} = \frac{T_{\text{TC}}}{T_{\text{total}}} \times 100\%
Tensor Core 利用率等于其活跃时间占总执行时间的百分比,用来衡量“魔法蒸锅”的开火率。
  1. 利用率 U_TCTensor Core 流水线保持忙碌的时间占比,是判断计算单元是否被有效使用的第一眼指标。
    UTCU_{\text{TC}}
  2. TC 活跃时间 T_TC采样周期内 Tensor Core 矩阵运算单元处于工作状态的累计周期数。
    TTCT_{\text{TC}}
  3. 总执行时间 T_total内核在 SM 上的全部耗时,包含计算、访存与各种等待周期。
    TtotalT_{\text{total}}
  4. 百分比换算把比值放大 100 倍并加上百分号,得到我们熟悉的 0% 到 100% 的读数。
    ×100%\times 100\%

内存带宽分析

传菜员从仓库到厨房的通道,决定了每秒能搬多少食材。这条通道就是显存与 SM 之间的 HBM 总线,它的“宽度”就是内存带宽。如果通道已经塞满,而蒸锅还在饿肚子,问题就出在供给端而不是烹饪端。

带宽利用率的定义是实测带宽除以峰值带宽,其中实测带宽等于内核读写总字节数除以内核耗时。当这个比值逼近 1,说明数据通道已经满负荷运转,此时再多的算力也插不上手,必须从减少搬运量或提高局部性入手。

除了总量,还要看访存质量:合并访问能把相邻线程的请求拼成一整趟运输,随机跨步访问则让每次搬运都装载不足;L2 缓存命中相当于在厨房门口建了一个小冷库,许多食材不必每次都回大仓库取。Nsight Compute 的 Memory Workload Analysis 面板会同时给出 DRAM 吞吐、L1/L2 命中率等分层指标,正好用来做这套“物流审计”。

传菜通道一旦饱和,蒸锅就只能干等。要系统性回答“瓶颈到底在算力还是访存”,需要一张全局速查表——Roofline 模型。

UBW=BactualBpeakU_{\text{BW}} = \frac{B_{\text{actual}}}{B_{\text{peak}}}
内存带宽利用率是实测带宽与峰值带宽的比值,越接近 1 越说明数据供给接近饱和。
  1. 带宽利用率 U_BW衡量内存子系统繁忙程度的指标,反映“传菜通道”的拥堵情况。
    UBWU_{\text{BW}}
  2. 实际带宽 B_actual由内核读写数据的总字节数除以实测耗时计算得到,单位常用 TB/s 或 GB/s。
    BactualB_{\text{actual}}
  3. 峰值带宽 B_peak硬件手册上的理论最大带宽,例如 A100 的 HBM 约为 1.6 TB/s,是一个恒定上限。
    BpeakB_{\text{peak}}

Roofline模型

顾问给老板画了一张图:横轴是“口味密度”,即一斤食材能做出几道菜;纵轴是出菜速度。图上有两条天花板:一条水平的“锅产能天花板”,一条斜的“上菜速度斜坡”。任何菜品都只能落在两条线形成的折线以下。

这就是 Roofline(屋顶线)模型。横轴是操作强度,即每搬运 1 字节数据能执行多少次浮点运算;纵轴是可达性能。水平线对应算力峰值,斜坡对应带宽峰值乘以操作强度,两条线的交点叫拐点。落在斜坡段的算子是访存受限,落在平台段的算子是算力受限,拐点附近则是理论上最均衡的甜蜜点。

以 A100 为例:FP16 Tensor Core 算力峰值约 312 TFLOPS,HBM 带宽约 1.6 TB/s,拐点约 195 FLOP/Byte。绝大多数 Transformer 里的逐元素算子操作强度都远低于这个值,所以天然落在访存受限区——这也是为什么“算子融合”会成为大模型优化的第一选择。

有了这张速查表,老板不再凭感觉改造:先查菜品落在哪个区,再决定是“修锅”还是“修路”。下一节继续用监控回答:即使知道了区域,具体停滞的每一秒又是怎么浪费的?

P=min⁡(Ppeak,  Bpeak×I),I=WQP = \min\left(P_{\text{peak}},\; B_{\text{peak}} \times I\right),\qquad I = \frac{W}{Q}
可达性能取“算力天花板”与“带宽斜坡”两者的较小值;操作强度是计算量除以访存量。
  1. 操作强度 I平均每搬运 1 字节数据能执行的浮点运算次数,单位 FLOP/Byte。
    I=WQI = \frac{W}{Q}
  2. 计算量 W算子总的浮点运算次数,单位 FLOP,是“菜谱”里总共有多少道工序。
    WW
  3. 访存量 Q算子读写显存的总字节数,单位 Byte,是“食材”总共被搬运了多少吨。
    QQ
  4. 带宽限制下的性能每秒钟最多搬入 B_peak 字节,若每字节能做 I 次运算,上限就是两者相乘。
    Bpeak×IB_{\text{peak}} \times I
  5. 取最小值 min实际可达性能永远等于两条限制线中较低的那一条,像屋顶的檐口一样封顶。
    min⁡(⋅)\min(\cdot)
  6. 算力峰值 P_peak硬件理论上每秒最多能完成的浮点运算数,例如 A100 的 FP16 峰值。
    PpeakP_{\text{peak}}

停滞原因诊断

回放监控时,老板发现了更多细节:不少厨师手举到一半停在原地发呆。有人眼巴巴等食材从传送带尽头送过来,有人等上一道工序的调料(数据依赖),有人被并排的同事挡住,还有人因为和搭档拿着两套菜谱而互相掣肘。

GPU 中 warp 的“发呆”在 Nsight Compute 里被归类为 Stall Reasons。常见的包括:long scoreboard(等待显存或 L2 返回数据)、short scoreboard(等待寄存器或算术单元结果)、barrier(等待同步)、branch resolving(等待分支解析)、math pipe throttle(算术流水线拥塞)。在 Warp State 面板里,这些原因会按占比列出,一眼就能看出“发呆的大头”。

停滞占比表示 warp 周期中花在等待上的比例。注意:SM 利用率高并不等于没有停滞——如果所有 warp 都在等内存,SM 依然显示忙碌,但真正干活的周期很少。诊断的要点是把停滞原因与上一节的瓶颈区域关联:访存受限通常伴随 long scoreboard 居高不下;算力受限则常见 math pipe throttle;分支发散往往对应数据排布不规整。

老板把发呆分为“等食材、等佐料、等位子、等口令”四类,每类都有不同解药:提高访存并行度、提升指令级并行、调节占用率、消除分支发散。对症下药之后,最后一步是减少“同一批食材被反复搬进搬出”——这就是算子融合。

Rstall=CstallCtotalR_{\text{stall}} = \frac{C_{\text{stall}}}{C_{\text{total}}}
停滞占比等于停滞周期数除以总周期数,量化了并发线程在“干等”上浪费的时间比例。
  1. 停滞占比 R_stallwarp 状态为等待的周期占总周期的比例,是并行效率的“照妖镜”。
    RstallR_{\text{stall}}
  2. 停滞周期 C_stall所有 warp 因各类原因停滞的周期计数之和,由 Nsight Compute 直接统计。
    CstallC_{\text{stall}}
  3. 总周期 C_total内核执行期间的全部时钟周期,是停滞占比的分母基准。
    CtotalC_{\text{total}}

算子融合优化

老板发现:原来洗菜、切菜、炒菜是三个独立工位,洗完的菜要装箱送回仓库,切菜时再从仓库取回,炒菜时再取一回。三个工位之间,食材在仓库进进出出,白白耗尽了传送带的运力,出菜慢的根源恰恰在这里。

算子融合正是把多个内核合并成一个:中间结果不再写回显存,而是留在寄存器、共享内存或 L2 缓存中,由下一个阶段直接消费。比如把 scale、relu、bias 三个逐元素算子合为一个内核,访存从六次(每个算子读一次写一次)降到两次(只读最开始的输入、只写最终的输出)。

在访存受限场景,融合带来的理论加速比约等于访存量下降的倍数。这正好把前三节的分析串成一条完整的优化建议流水线:先用 Roofline 判断方向,再用 stall 诊断补充证据;访存受限优先融合与提升局部性,算力受限则去 padding、降精度、减少冗余计算;每一步改造后都用 Nsight Compute 复测验证,形成闭环。

至此,老板拥有了完整的“厨房效率手册”:装监控(采集)→ 拆时间 → 查蒸锅 → 查通道 → 画速查表 → 分类发呆 → 流水线融合 → 复测验证。Tensor Core 性能分析,本质上就是这套“用数据定位、按瓶颈施策”的工程方法。

Sfusion=QbeforeQafterS_{\text{fusion}} = \frac{Q_{\text{before}}}{Q_{\text{after}}}
融合加速比等于融合前访存量除以融合后访存量,是访存受限场景下预估提速的理论上限。
  1. 融合前访存量 Q_before每个内核各自读写中间结果的总字节数,搬运次数越多浪费越大。
    QbeforeQ_{\text{before}}
  2. 融合后访存量 Q_after只保留第一个内核的输入读取与最后一个内核的输出写回,中间结果留在片上。
    QafterQ_{\text{after}}
  3. 加速比 S_fusion当瓶颈是访存时,时间近似正比于访存量,因此下降倍数约等于加速倍数。
    SfusionS_{\text{fusion}}

AI 应用场景

大模型训练中的 Tensor Core 调优

阶段:模型训练与性能优化

解决的问题:训练团队报告 GPU 利用率只有 30%,却说不清瓶颈在哪。传统做法是凭经验反复调整 batch size 和并行策略,盲目且低效。用 Nsight Compute 采集后,发现 MoE 层的 gate 网络分支发散严重,专家权重访存不连续导致 long scoreboard 高企;再结合 Roofline 判定为访存受限,通过专家权重重排与算子融合(把 gate 前的归一化与矩阵乘合并),有效 Tensor Core 利用率从 22% 提升到 41%,模型 FLOPs 利用率(MFU)提升约 40%。

具体案例:某 70B MoE 模型训练任务,原先 40 分钟一个 step;优化后缩短到 28 分钟,单轮训练节省数天 GPU 机时。

LLM 推理服务的访存瓶颈治理

阶段:推理部署与延迟优化

解决的问题:LLM 推理 decode 阶段一次只生成一个 token,计算强度很低,属于典型的访存受限:KV Cache 读取与权重搬运占主导。Roofline 分析显示算子大多落在斜坡段,一味增大 batch 反而让带宽更快耗尽。通过把 QKV projection 与 RoPE 算子融合,并用 4-bit 量化压缩 KV Cache,中间张量不再反复写回显存,单 token 延迟下降 35%,吞吐提升近一倍。

具体案例:某在线对话服务的 FP16 引擎在 batch=64 时 TTFT 抖动明显;改造后 P99 延迟从 210ms 降到 135ms,GPU 数量减半仍满足 SLA。

算子库开发中的 Roofline 回归测试

阶段:算子开发与基准测试

解决的问题:算子库维护者每次提交新 kernel,都需要判断性能是否逼近硬件极限。传统做法是与旧版本比速度,无法说明绝对优化空间。团队把 Roofline 理论峰值接入 CI 流水线:每次提交自动输出“当前算子距离屋顶线还有多少差距”,并标注是访存受限还是算力受限;超过阈值自动告警,引导开发者选择算子融合或改进访存布局。

具体案例:某图像预处理算子库在 CI 中暴露 0.6 倍屋顶线差距,经融合三个 elementwise kernel 后提升到 0.88 倍。

Python 演示

python44 行
"""Roofline 瓶颈判定与算子融合收益估算演示"""import math COMPUTE_PEAK = 312.0   # 算力峰值 TFLOPS (FP16 Tensor Core)MEM_BW = 1.6           # 内存带宽峰值 TB/s (HBM) def arithmetic_intensity(flops, bytes_moved):    """计算操作强度: 每搬运 1 字节数据能执行多少 FLOP"""    return flops / bytes_moved def roofline_perf(flops, bytes_moved):    """Roofline 模型: 可达性能取算力线与带宽线的较小值"""    ridge = COMPUTE_PEAK / MEM_BW    intensity = flops / bytes_moved    perf = min(COMPUTE_PEAK, MEM_BW * intensity)    kind = "算力受限" if intensity >= ridge else "访存受限"    return perf, intensity, ridge, kind def fusion_benefit(kernels):    """融合前后访存量对比: 中间结果不再写回显存"""    before = sum(k["read"] + k["write"] for k in kernels)    after = kernels[0]["read"] + kernels[-1]["write"]    return before, after, before / after def main():    kernels = [        {"name": "scale", "read": 2.0, "write": 2.0},        {"name": "relu",  "read": 2.0, "write": 2.0},        {"name": "bias",  "read": 2.0, "write": 2.0},    ]    before, after, speedup = fusion_benefit(kernels)    print("== 算子融合收益 ==")    print("融合前访存 {:.1f} GB, 融合后 {:.1f} GB".format(before, after))    print("访存下降 {:.2f} 倍, 访存受限时预估加速 {:.2f} 倍".format(speedup, speedup))     flops = 1.0e13    bytes_moved = after * 1.0e9    perf, intensity, ridge, kind = roofline_perf(flops, bytes_moved)    print("\n== Roofline 判定 ==")    print("操作强度 {:.1f} FLOP/Byte, 拐点 {:.1f} FLOP/Byte".format(intensity, ridge))    print("可达性能 {:.1f} TFLOPS, 瓶颈类型: {}".format(perf, kind)) if __name__ == "__main__":    main()
目的:用约 40 行代码模拟 Tensor Core 性能分析的核心两步——用 Roofline 判定算子瓶颈类型,并估算算子融合带来的访存收益。
  1. COMPUTE_PEAK = 312.0声明屋顶线里的水平天花板:显卡每秒最多能算多少 TFLOP,这里对应 A100 FP16 峰值。
  2. MEM_BW = 1.6声明斜坡的斜率:内存每秒最多能搬多少 TB 数据,对应 A100 HBM 峰值带宽。
  3. ridge = COMPUTE_PEAK / MEM_BW求拐点:操作强度高于它就算力受限,低于它则访存受限。
  4. perf = min(COMPUTE_PEAK, MEM_BW * intensity)屋顶线核心公式:可达性能永远取两条限制线的较小值。
  5. kind = "算力受限" if intensity >= ridge else "访存受限"用拐点把算子分进两个瓶颈区域,决定优化方向。
  6. before = sum(k["read"] + k["write"] for k in kernels)融合前每个内核都要读写一遍显存,把三次搬运全部相加。
  7. after = kernels[0]["read"] + kernels[-1]["write"]融合后只在最前读一次、最后写一次,中间结果留在芯片内。
  8. roofline_perf(flops, bytes_moved)一次调用同时返回可达性能、操作强度、拐点与瓶颈类型。
  9. if __name__ == "__main__":让脚本既能被 import 也能直接运行,输出两类分析结果。

常见误区

误区我看了 Nsight Compute,Tensor Core 利用率才 20%,肯定是显卡太弱,换 A100、H100 就能解决。

正解换卡只能抬高“算力天花板”,但如果瓶颈在数据供给,性能几乎不会变。用 Roofline 一看,若算子落在访存受限区,换卡后水平线升高而斜坡不变,可达性能仍被带宽摁住。先做算子融合、调整访存布局,再考虑升级硬件,才是正确的顺序。

为何常见:人习惯把“利用率低”直接等同于“硬件不行”,忽略了利用率低往往是因为数据喂不饱。

误区我调优的目标就是摆脱“访存受限”,只要进入“算力受限”就代表优化成功了。

正解两种受限只是方向标,不是优劣标签。算力受限意味着已贴近算力天花板,进一步优化的空间很小;访存受限反而说明算力还有大量余量,算子融合、缓存优化、数据压缩等手段能带来倍数级收益。真正该追求的不是“换一种受限”,而是让性能点尽量贴近屋顶线的拐角。

为何常见:对“限制”二字的直觉判断,让人误以为“受限”就是坏结果。

误区我通过加 padding 把矩阵补得整整齐齐,利用率冲到 98%,任务应该更快了吧?可实际速度反而变慢了。

正解利用率是“时间占比”,不是“有效计算占比”。大量 padding 让 Tensor Core 在算大量的“零”,流水线确实忙碌,但真正有用的 FLOPs 占比很低。还应对比实际 FLOPs 与理论最小 FLOPs,评估有效计算的比例,而不是只盯一个占用率数字。

为何常见:单一 KPI 驱动的思维惯性,指标好看但真实收益不达预期,忽略了“有效”与“忙碌”的区别。

误区我已经把三个算子的 CUDA 代码写进同一个函数了,为什么 Nsight Compute 还是显示三个内核?

正解融合的本质是让中间结果留在片上存储(寄存器、共享内存、L2),消除“写回显存再读回”的往返。如果只是源码位置相邻,每个算子仍各自分配显存并单独 launch,那依然是多个内核。判断标准很简单:Nsight Compute 的 kernel 列表里是否只剩一个。

为何常见:望文生义,把源码组织方式与内核调度机制混为一谈。

误区我每次跑完只看 SM 利用率,90%,说明优化到位了,报告里其他东西没必要看。

正解SM 利用率高不代表没有浪费:如果所有 warp 都在 long scoreboard 等内存,SM 依然显示“忙”,但大部分周期都在空转。必须结合 Warp State、Stall Reasons、Tensor 流水线利用率、缓存命中率等多维指标交叉判断,才能定位真正的浪费。

为何常见:人眼偏好用单一数字做结论,而 GPU 性能问题恰恰是多因素耦合的。

面试题

Q1. 下列关于 Nsight Compute 的说法,正确的是?

单选题 · easy

  • A.主要用于监测 GPU 温度功耗
  • B.能够深入指令级剖析内核← 正确答案
  • C.只能统计进程级整体负载
  • D.是 NVIDIA 的自动调参库

答案:B。Nsight Compute 是 NVIDIA 的指令级性能剖析工具,能深入内核内部查看各流水线吞吐、warp 停滞、缓存命中等信息。功耗温控属于 nvidia-smi 或 DCGM 的范畴;进程级负载与自动调参也都不是它的定位。就像后厨的监控探头看的是每一位厨师的细动作,而不是门口测温枪读个体温。

Q2. Tensor Core 利用率的计算中,分母通常取?

单选题 · easy

  • A.张量核心活跃时长
  • B.核函数总执行时间← 正确答案
  • C.显存数据搬运时间
  • D.应用进程启动耗时

答案:B。利用率的分子是 Tensor Core 活跃时间,分母是整个内核在 SM 上的总执行时间(含等待与访存周期)。若把分母换成 TC 活跃时间会恒等于 100%;显存时间或启动耗时都不是该指标的分母。就像计算蒸锅开火率要用营业时间做分母,而不是用开火时间。

Q3. Roofline 模型的横轴通常表示?

单选题 · easy

  • A.内存访问带宽峰值情况
  • B.计算操作强度的大小← 正确答案
  • C.芯片核心频率的高低
  • D.线程块数量的多少

答案:B。Roofline 横轴是操作强度(FLOP/Byte),纵轴是可达性能。操作强度是算子的固有属性,由计算量与访存量决定,与硬件频率、带宽无关;带宽和频率只影响天花板线的位置。就像“口味密度”取决于菜谱本身,而不是锅的大小。

Q4. Roofline 中拐点的正确计算方式是?

单选题 · mid

  • A.算力峰值除以带宽峰值← 正确答案
  • B.带宽峰值除以算力峰值
  • C.算力峰值乘以带宽峰值
  • D.算力峰值加上带宽峰值

答案:A。拐点由两条限制线的交点解出:令带宽限制 B×I 等于算力峰值 P,可得 I = P / B。反过来、相乘或相加都会破坏量纲。拐点左侧访存受限,右侧算力受限,是决定优化方向的分水岭。

Q5. 某算子计算量 200 GFLOP,访存量 2 GB,拐点为 150 FLOP/Byte,其瓶颈属于?

单选题 · mid

  • A.访存受限类型的瓶颈← 正确答案
  • B.算力受限类型的瓶颈
  • C.两者同时受限的瓶颈
  • D.数据不足难以判断

答案:A。操作强度 I = 200×10^9 / (2×10^9) = 100 FLOP/Byte,小于拐点 150,落在斜坡段,属于访存受限。此时提升算力没有意义,应通过算子融合、减少访存量来拉高操作强度,让性能点沿斜坡向上爬。

Q6. 在 Warp 停滞原因中,long scoreboard 通常对应?

单选题 · mid

  • A.等待显存或 L2 数据返回← 正确答案
  • B.等待算术单元计算结果
  • C.等待同步栅栏信号释放
  • D.等待分支指令解析完成

答案:A。long scoreboard 指等待显存或 L2 这类“远距离”数据返回,是访存受限算子里最常见的停滞原因;等待算术单元结果属于 short scoreboard;barrier 与分支解析则是另外两类停滞。就像厨师等传送带尽头的食材,与等手边的调料是两种不同的发呆。

Q7. 算子融合带来加速的直接原因是?

单选题 · mid

  • A.显著减少了计算量规模
  • B.显著减少了中间结果访存← 正确答案
  • C.提高了算术流水线精度
  • D.增大了线程块的数量

答案:B。融合的本质是让中间结果留在片上存储(寄存器、共享内存、L2),不再写回显存又读回,因此直接减少访存量。计算量、精度、线程块数量都不是融合的直接目标。就像洗切炒三段合一条流水线,食材不再装箱入库。

Q8. Nsight Compute 能够报告的信息包括?

多选题 · hard

  • A.各指令流水线的吞吐量← 正确答案
  • B.Warp 停滞原因的分布← 正确答案
  • C.L1 与 L2 缓存命中率← 正确答案
  • D.主板上电容老化程度

答案:ABC。Nsight Compute 聚焦指令级性能:指令吞吐、warp 停滞原因、缓存命中率都在其报告范围内;主板电容老化属于硬件健康监测,不在性能剖析工具的职责内。选 D 的同学是把“硬件监控”和“指令剖析”混为一谈了。

Q9. 某算子在 A100 上实测:算力峰值 312 TFLOPS,带宽峰值 1.6 TB/s,操作强度 100 FLOP/Byte,预测可达性能约为?

单选题 · hard

  • A.160TFLOPS← 正确答案
  • B.200TFLOPS
  • C.312TFLOPS
  • D.100TFLOPS

答案:A。操作强度 100 小于拐点 195,属于访存受限。可达性能 = min(312, 1.6×100) = 160 TFLOPS,而不是算力峰值 312。这正好说明:当数据供给跟不上时,再强的算力也只能被带宽“摁”在斜坡上。

Q10. 下列哪些情况会导致 Tensor Core 利用率偏低?

多选题 · extreme

  • A.矩阵块排布未对齐尺寸← 正确答案
  • B.内存带宽长期处于饱和← 正确答案
  • C.活跃线程块数量过少← 正确答案
  • D.算力已逼近理论峰值

答案:ABC。矩阵排布不对齐使 Tensor Core 难以形成有效的矩阵乘;带宽饱和使 TC 空等数据;活跃线程过少则无法用并行掩盖延迟——三者都会拉低利用率。而“算力已逼近峰值”说明 TC 正在满负荷工作,利用率不会低,因此 D 不选。