在繁忙的食堂后厨里,大厨做番茄炒蛋要过三道工位:一号工位洗番茄,二号工位切块,三号工位打蛋。麻烦的是,每道工位做完都要把半成品装进保鲜盒、放回储物柜,下一道工位再从柜子里取出来。一盘菜还没下锅,大厨已经来回开了五六次柜门。深度学习推理也一样:模型是一张计算图,每个算子(卷积、批归一化、激活、矩阵乘……)就像一道工位,执行完要把中间结果写回内存,下一个算子再读回来。算子融合(Operator Fusion / Kernel Fusion),就是把这些相邻工位合并成一个“料理台”:洗好直接切,切好直接下锅,中间结果在台面上交接,不再来回存取。本文用这个厨房比喻,把融合原理、收益分析、Conv-BN-ReLU 与 MatMul-Add 两种经典融合、手写与编译器自动融合、性能评估和融合策略一网打尽,让“推理加速”不再神秘。
对 AI 从业者而言,掌握算子融合意味着真正理解推理引擎的加速原理——从“会部署模型”进阶到“能优化模型运行时”,这是模型部署、推理引擎开发与端侧加速岗位的核心竞争力。
可视化演示
展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。
本节配有交互动效(进入视口后自动加载,约 3KB)。
系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T
融合基本原理
大厨做番茄炒蛋时,一号工位洗番茄、二号工位切块、三号工位打蛋,每一道做完都要把半成品装进保鲜盒放回储物柜,下一道再取出来。深度学习推理正是这个场景:模型是一张计算图,每个节点是一个算子——卷积、批归一化、激活、矩阵乘法等等。每个算子由推理引擎启动一个内核(Kernel)来执行,输入输出都放在全局内存中。相邻算子之间,必然发生一次“上一个算子写中间结果,下一个算子读中间结果”的往返。
算子融合(Operator Fusion)就是把这些相邻算子合并成一个内核,让中间结果留在寄存器或片上缓存里直接交接,不经过全局内存。这是推理引擎中最常用、也最直观的一种图优化手段。融合后的执行图节点变少,每个节点干的活变多,但数据搬运和调度开销显著下降。
如果我们把一次推理的总时间写出来,就能看清融合省在哪里:
回到厨房:融合就像把洗、切、打蛋三个工位并成一个料理台,半成品在台面上直接交接,柜门一次都不用开。理解了这一点,后面所有收益分析和融合模式都是在这个“少开柜门”的道理上展开的。
- 总时间分解端到端推理延迟等于所有内核延迟之和,每个内核的时间是四项开销累加
- 启动开销每次调用内核都有固定启动延迟,N 越小则启动总开销越小,这是融合的直接收益来源
- 访存开销读写全局内存最贵,融合让中间结果不落内存,相当于从求和中去掉若干无效访存项
- 求和意义N 从 3 变成 1,启动与同步项变为原来的三分之一,中间访存项直接消失
融合收益分析
厨房里决定两个工位是否合并,要看“存取储物柜的时间”和“真正动手处理的时间”谁占大头。如果大半时间都耗在开柜取放上,合并收益自然大;如果本来处理就很慢,合并也快不了多少。计算机里衡量这个比例的标准叫算术强度(Arithmetic Intensity)。
融合收益不是玄学,是可以量化的:先用 profiler 数出融合前后“内核数量”和“中间张量字节数”,再乘以硬件实测的内存带宽与内核启动延迟,就能算出理论加速。对访存密集的小算子组合,融合往往能带来 1.5~3 倍的端到端提升;对本来就计算密集的大算子,收益则有限。这就是为什么先分析再动手,比盲目合并更靠谱——毕竟省柜门时间的前提,是柜门时间真的占了大头。
- 计算量FLOPs 即浮点运算次数,代表“动手处理”的总工作量
- 访存量Bytes 是内核从全局内存读出和写回的字节总数,代表“存取储物柜”的流量
- 比值含义I 低时,算子的瓶颈在内存带宽而不是运算单元,少搬数据就能快,所以融合收益大
- 收益量化融合三项收益逐条可测——中间访存字节数下降、内核启动次数下降(N-1 次启动被省掉)、缓存局部性提升(数据连续被复用)
Conv-BN-ReLU融合
洗菜、切菜、焯水是三道工序。焯水要用盐水,但大厨可以在切菜时就把盐撒在番茄块上,后面直接下锅,省掉“取盐、配盐水”这一步。这就是参数折叠的思想。在神经网络里,卷积后面几乎总跟着批归一化(Batch Normalization)和 ReLU 激活,三者形影不离,是融合的头号目标。
训练阶段,BN 用每个批次的统计量做归一化;推理时统计量已固定,BN 就变成了一个纯粹逐通道的线性变换。于是我们可以把它直接折叠进前面卷积的权重和偏置里,再让 ReLU 紧随其后,三个算子合成一个内核。
实际部署中,TensorRT、ONNX Runtime、NCNN 等引擎都会自动完成这个折叠。折叠后卷积核和偏置各多一份“预调整”后的副本,参数总量不变,运算却少了两整个内核的数据往返。就像把盐提前撒在番茄块上,下锅那一瞬间,所有准备都已完成。
y_c = \frac{x_c - \mu_c}{\sqrt{\sigma_c^2 + \varepsilon}} \cdot \gamma_c + \beta_c\quad\Longrightarrow\quadw_c' = w_c \cdot \frac{\gamma_c}{\sqrt{\sigma_c^2 + \varepsilon}},\;\;b_c' = (b_c - \mu_c) \cdot \frac{\gamma_c}{\sqrt{\sigma_c^2 + \varepsilon}} + \beta_c- BN 参数含义μ_c 与 σ_c² 是训练阶段统计出的逐通道均值与方差,推理时冻结为常数;γ_c 与 β_c 是可学习的缩放和平移参数
- 防零常数ε 是一个极小正数,避免除零,通常在 1e-5 量级
- 缩放系数令 s_c 表示该通道的折叠缩放因子,折叠后的卷积核等于原卷积核逐通道乘以 s_c
- 偏置折叠原偏置先减均值再乘缩放,最后加 β,得到新偏置,把 BN 的平移吸收进来
- 等价替换Conv→BN→ReLU 替换为“用 w'、b' 做卷积 + ReLU”,两者输出逐元素数值等价,但内核数从 3 变 1
MatMul-Add融合
调好的酱汁直接淋在菜上是一步,先盛出来放旁边、上桌前再浇一遍,就是两步。线性层(全连接)、注意力打分、Transformer 的投影层,几乎都是“矩阵乘完马上加偏置”的结构,即 GEMM 后紧跟 Add。未融合时,A×B 的结果矩阵被完整写回显存,Add 内核再读出来逐元素加 bias,白白多了一次矩阵规模的写与读。
融合的做法很聪明:不需要额外内核,只要在矩阵乘的“尾声”(epilogue)阶段,把累加器的初始值设成 bias_j。乘加循环结束后每个输出元素天然带着偏置,直接写回一次即可。
这个融合模式在 Transformer 类模型里收益尤其明显:一个 512×512 的中间矩阵写回再读回,就是 2MB 的显存流量被省掉,而注意力头越多、序列越长,节省越可观。省掉的不仅是流量,还有 Add 内核的启动开销——酱汁不再需要先盛出来放旁边了。
- 输出元素C_ij 表示输出矩阵第 i 行第 j 列的值,由 A 的第 i 行与 B 的第 j 列内积再加偏置得到
- 内积累加对 k 从 1 到 K 做乘累加,这是 GEMM 最核心的循环体
- 偏置广播bias_j 只与列号 j 相关,同一列的所有行共享同一个偏置值,逐元素相加即可
- 融合实现将累加器寄存器初始化为 bias_j,循环结束自动得到带偏置结果,等价于数学上先求和后加 bias
手写融合算子
有的大厨不信任自动厨具,非要自己设计整套连贯动作:自己写菜谱、自己拿捏火候、自己决定什么时候该把菜铲到哪个锅里。手写融合算子也是这样——直接写一个 CUDA 内核,把卷积主循环、折叠后的权重、ReLU 激活全部写进同一个 kernel。它的核心技巧是循环合并(Loop Fusion):原本三个算子的三层循环,合并成一个外层滑动窗口循环,内层只做一次乘累加、一次激活、一次写回。
线程块设计上,每个线程负责计算一个输出像素,输入 patch 预先加载到共享内存或寄存器里反复复用;手工调优则围绕 unroll 次数、block 尺寸、寄存器上限进行。要理解手写内核的优化空间,先要知道卷积本身的计算量有多大:
计算量摆在这里,融合能做的不是减少它,而是让每一次运算都“吃得到”数据——输入 patch 从共享内存取、输出写回一次、激活在寄存器里顺手完成。手写融合的代价是开发成本高、可移植性差,换一个硬件平台可能就要重写。但它能榨出编译器自动融合漏掉的最后一点性能,这也是很多芯片厂商为旗舰模型定制融合内核的原因。
- 乘加计数一次乘和一次加共 2 个 FLOP,所以前面乘上 2
- 输出空间H_out × W_out 是输出特征图的空间尺寸,每个输出像素都要独立算一轮
- 通道与核C_in × C_out × K² 表示每个输出像素要对所有输入通道的 K×K 窗口做乘累加
- 总运算量四个维度乘起来就是一次卷积的全部 FLOPs,它是硬性计算成本,融合不改变它
编译器自动融合
智能厨具拿到整套菜谱后,会自动识别“洗→切→焯水”这类固定套路,把它合并成一个预设程序,大厨什么都不用改。编译器自动融合就是这套智能厨具:推理引擎内置图优化 Pass,遍历计算图,用模式匹配识别出 Conv→BN→ReLU、MatMul→Add 这类子图,整体替换成一个融合算子节点。
TVM 的 FuseOps Pass、TensorRT 的 layer fusion、ONNX Runtime 的 graph optimization、NCNN/MNN 的算子合并,都是这个套路。替换之后,调度器(auto-scheduler 或人工模板)决定融合后的内核如何分块、如何映射到硬件。自动融合依赖一个代价模型来评估“这个融合到底值不值”:
编译器自动融合的价值在于“零侵入”:模型代码一行不改,导入引擎后由图优化自动完成。代价是它对非常规子图的识别能力有限,且自动生成的代码有时不如手写内核极致。实际工程中,常见做法是“编译器自动融合打底,热点子图手写内核补刀”——智能厨具负责日常,大厨亲自出马处理招牌菜。
- 启动开销t_启动 是内核启动的固定延迟,融合后内核数减少,这项被压缩
- 计算耗时FLOPs 除以硬件峰值算力 P_峰值,得到理想计算时间
- 访存耗时Bytes 除以有效内存带宽 B_带宽,得到理想访存时间,融合削减中间张量后这一项下降明显
- 取较大者真实内核受更快到达瓶颈的一方约束,代价模型因此取二者最大值
性能评估方法
新工序好不好,不能只看单步快不快,要看整桌菜的平均出菜时间、高峰客流的稳定性、占用台面空间。评估融合效果同样要全面:端到端延迟是最核心指标,但只报一次最快值没有意义,要取多次采样的 p50/p99 稳定值,并做 warm-up 消除冷启动影响。
除了延迟,还要看吞吐量(每秒处理多少张图)、峰值内存(融合后中间张量减少通常带来显存下降)、以及内核数量与带宽利用率的 profiler 数据。不同硬件平台上融合表现可能完全不同,A/B 对比要在目标设备上跑。加速比是最直观的定量指标:
评估不是一次性的:融合策略修改后要回归测试,量化部署后还要再测一遍,因为低精度推理的访存行为会变。就像大厨换了个新灶台,招牌菜的味道必须重新试吃确认——性能数据就是推理引擎的“试吃报告”。
- 基线延迟T_未融合 是优化前模型端到端平均延迟,作为对比基准
- 优化延迟T_融合 是融合后同样的数据、同样的设备上测得的平均延迟
- 加速比含义S 即“原来花几份时间,现在花一份时间”,1.5 表示提速 50%
- 判定准则S>1 融合有效;S≈1 收益可忽略,需结合稳定性判断;S<1 说明发生了寄存器溢出或并行度下降,必须回退
融合策略设计
不是所有菜都适合“一锅出”:有的菜分锅炒更香,融得太狠反而糊锅。融合策略就是要回答“哪些算子该合、哪些该拆”。判断标准有四问:这个算子访存是否密集(算术强度远低于硬件平衡点)?中间结果是否没有其他分支依赖?融合后中间数据能否塞进寄存器或共享内存?融合会不会让并行度明显变差?
把这四问变成可计算的判据,就是代价模型。用省下的访存时间减去省下的启动时间作为融合净收益:
端侧场景还有额外约束:NPU 和移动 GPU 的片上缓存很小,融合粒度过大会导致中间数据溢出、回退到低速路径;超大算子(如大卷积核、超大 GEMM)则保留单算子,以利用专用的张量指令。融合策略设计的本质,是在“少开柜门”和“别把锅撑爆”之间找平衡——不是融得越多越好,而是融得恰到好处。
- 消除的数据量M_消除 是融合后不再写回读回的中间张量总字节数
- 省下的访存时间M_消除 除以有效内存带宽 B_带宽,即少搬这些数据省下的秒数
- 省下的启动时间N_原 个内核融合成 1 个,省掉 N_原-1 次内核启动
- 净收益判定G>0 融合有净收益,G<0 则维持原计算图,避免负优化
AI 应用场景
端侧手机 App 实时美颜加速
阶段:推理计算图优化(部署阶段)
解决的问题:老机型跑美颜模型每帧高达 30ms,瓶颈不是计算量,而是几十个小算子轮流启动、中间张量反复读写。传统做法直接换更强芯片,成本高且换代快。通过在 NCNN/MNN 推理引擎中开启算子融合,把 Conv-BN-ReLU 序列图结构自动合并,kernel 数从 40 降到 15,帧耗时降至 18ms,不动模型结构就解决了卡顿。
具体案例:某美颜 App 的人像分割网络由 MobileNet 骨干加 BN-ReLU 组成,部署工程师导出计算图后开启自动图优化,再对瓶颈子图手写融合内核,最终在骁龙 8 系手机上实现实时 30FPS。
自动驾驶域控上的 TensorRT 加速
阶段:车端 GPU 部署优化
解决的问题:目标检测模型含大量 Conv-BN-ReLU 与 MatMul-Add 组合,原始 ONNX 图直接跑 TensorRT 时 GPU 利用率低、延迟超时。传统优化靠人工改网络结构,风险高。利用 TensorRT 的自动 layer fusion 和 BN 参数折叠,端到端延迟从 12ms 降到 8ms,满足 30ms 帧预算的余量大幅提升。
具体案例:某 L2+ 自动驾驶方案的 3D 目标检测模型,部署工程师对比融合前后 profiler 数据,确认内核数从 280 个降至 96 个,显存峰值下降约 1.2GB,最终通过车规级延迟测试。
边缘 AI 摄像头 NPU 部署的融合策略
阶段:融合策略设计与代价模型评估
解决的问题:边缘盒子的 NPU 片上 SRAM 仅几 MB,盲目融合导致中间数据溢出触发 fallback,反而变慢。传统手工试错耗时且不可迁移。通过代价模型计算每个候选融合的净收益 G,并结合片上缓存容量挑选“半融合”方案,如只做 BN 折叠、不做跨层大融合,平衡性能与稳定性。
具体案例:某智慧园区摄像头部署 YOLOv5s,平台工程师在芯片 SDK 的图编译阶段配置融合白名单,依据算术强度与片上内存预算选融合项,最终推理帧率从 25FPS 提升到 40FPS,且无一次回退。
Python 演示
import numpy as np def conv2d(x, w, b): """单通道二维卷积,stride=1,same 填充,b 为标量偏置。""" H, W = x.shape K = w.shape[0] pad = K // 2 xp = np.pad(x, pad, mode='constant') out = np.zeros((H, W)) for i in range(H): for j in range(W): out[i, j] = np.sum(xp[i:i + K, j:j + K] * w) + b return out def relu(x): return np.maximum(x, 0.0) def bn_infer(y, gamma, beta, mu, var, eps=1e-5): """推理阶段的 BN:统计参数全部固定,只做线性变换。""" return gamma * (y - mu) / np.sqrt(var + eps) + beta def main(): rng = np.random.default_rng(42) x = rng.normal(size=(8, 8)) w = rng.normal(size=(3, 3)) b = 0.2 gamma = 1.3 beta = -0.1 mu = 0.05 var = 1.1 # 未融合:conv -> bn -> relu,三个内核产生两块中间张量 y1 = conv2d(x, w, b) y2 = bn_infer(y1, gamma, beta, mu, var) y_unfused = relu(y2) # 融合:先把 BN 折叠进卷积权重与偏置,再执行"卷积+ReLU" scale = gamma / np.sqrt(var + 1e-5) w_fused = w * scale b_fused = (b - mu) * scale + beta y_fused = relu(conv2d(x, w_fused, b_fused)) same = np.allclose(y_unfused, y_fused) assert same, '融合前后结果不一致' unfused_kernels = 3 fused_kernels = 1 unfused_mem_traffic = (y1.size + y2.size) * 4 * 2 # 两块中间张量各写回+读回 fused_mem_traffic = 0 saved = (1 - fused_mem_traffic / unfused_mem_traffic) * 100 print('融合前后输出一致:', same) print('内核启动次数: %d -> %d' % (unfused_kernels, fused_kernels)) print('中间张量内存往返(字节): %d -> %d' % (unfused_mem_traffic, fused_mem_traffic)) print('访存节省: %.1f%%' % saved) if __name__ == '__main__': main()
scale = gamma / np.sqrt(var + 1e-5)计算每个通道的折叠缩放系数,即 BN 参数折叠的核心一步w_fused = w * scale把 BN 的缩放吸收进卷积核,新卷积核直接可用b_fused = (b - mu) * scale + beta将均值和 β 平移吸收进偏置,BN 在运行时消失y_fused = relu(conv2d(x, w_fused, b_fused))融合后的计算路径只有“一次卷积 + 一次激活”assert same, '融合前后结果不一致'用断言强制保证数值等价,不满足则报错unfused_mem_traffic = (y1.size + y2.size) * 4 * 2统计未融合时两块中间张量的写回与读回总字节数out[i, j] = np.sum(...) + b卷积滑窗内的乘累加,模拟 GPU 内核的主循环
常见误区
误区我们部署时做了算子融合,模型的 FLOPs 变小了,所以推理才变快。
正解融合主要消除的是中间张量的写回与读回、以及内核启动次数,FLOPs 基本不变,个别情况甚至因边界填充略有增加。推理变快的真正来源是“省掉了装盒、存放、再取出”的访存与调度开销。用厨房比喻说:合并工位没有让切菜动作变少,而是省掉了来回开柜门的时间。
为何常见:人们习惯把“变快”直接归因于“算得更少”,忽略了内存搬运在推理中的真实占比,尤其是访存密集的小算子。
误区融合是数学变换,所以融合前后每个浮点数都应该一模一样,否则就是引擎有 bug。
正解数学上等价,但浮点运算次序被重排,卷积加 BN 变成单次乘加后,误差通常在 1e-6 量级,对精度影响可忽略。若应用对数值极其敏感,应在目标设备上做量化对比。等价性是“统计意义”上的,不是二进制 bit 级的一致。
为何常见:把“数学等价”误当成“浮点结果完全一致”,忽略了 IEEE 754 浮点运算不满足结合律这一事实。
误区计算图里挨着的两个算子,随手就能合到一起,融合器无脑合并就行。
正解合法融合要同时满足:两个算子输出形状一致、中间结果没有被其他分支引用、融合后保持数值等价、目标硬件指令支持该融合模式。编译器用依赖分析和模式匹配来判定,而不是看是否相邻。就像储物柜里的半成品可能有别的菜也要用,不能随便拿走。
为何常见:只看到拓扑相邻,忽略了数据依赖的多消费者问题,这是初学者设计融合策略时最常见的错误。
误区既然融合能省访存,那所有算子都该融合,越激进越快。
正解当算子本来就是计算密集、带宽充足时,融合省下的访存时间微乎其微;而融合后并行度下降、寄存器溢出导致 local memory 溢出反而更慢。成熟引擎都会用代价模型估算净收益 G,必要时回退。融合是“投资决策”,不是“无脑优惠券”。
为何常见:把“通常收益大”误当成“必然收益”,忽略了硬件瓶颈位置与资源约束的共同作用。
面试题
Q1. 算子融合最主要减少的是哪类开销?
- A.模型参数量
- B.中间内存访存← 正确答案
- C.浮点计算总量
- D.训练样本数量
答案:B。融合让中间结果留在寄存器或片上缓存,减少的是中间张量的写回与读回,以及内核启动次数。模型参数量和浮点计算总量基本不变,训练样本数量与推理优化无关。就像合并工位省的是开柜门时间,而不是切菜动作。
Q2. 推理阶段 BN 折叠进卷积的前提条件是什么?
- A.训练时每次批量数据足够大
- B.推理时 BN 统计参数已固定← 正确答案
- C.卷积核尺寸必须是 1×1
- D.输入图像必须是单通道灰度
答案:B。推理时 μ、σ² 来自训练集的固定统计量,γ、β 也是训练好的常数,BN 退化为线性变换,才能折叠进卷积。批量大小、卷积核尺寸、输入通道数都不是必要条件。
Q3. 算术强度 I = FLOPs/Bytes 很低,说明该算子最可能是?
- A.计算密集型算子
- B.访存密集型算子← 正确答案
- C.通信密集型算子
- D.并行度极高的算子
答案:B。算术强度低意味着每做一次浮点运算要搬很多字节数据,算子的天花板是内存带宽,属于访存密集型。这类算子融合收益最大,因为少搬中间数据就能直接提速。
Q4. Conv-BN-ReLU 融合后,新的卷积偏置 b' 的正确计算公式是?
- A.只含原始偏置与均值项
- B.(b-μ)×s+β 其中 s 为缩放系数← 正确答案
- C.包含均值方差与 γ 项
- D.仅包含缩放系数与偏置项
答案:B。令 s = γ/√(σ²+ε),折叠后的偏置 b' = (b-μ)×s+β,同时吸收均值平移、方差缩放和 β 平移。其他选项都漏掉了必须的平移或缩放项,数学上不成立。
Q5. 手写融合算子时,循环合并(Loop Fusion)的主要作用是?
- A.减少嵌套循环的层数
- B.让中间数据留在寄存器缓存← 正确答案
- C.增大模型可训练参数量
- D.压缩卷积核的存储大小
答案:B。循环合并把卷积、激活、写回放进同一循环体,中间结果在寄存器或共享内存中直接流转,不必写回全局内存再读回。层数减少只是表象,核心收益是数据就地复用。
Q6. 哪些情况适合作为算子融合候选?
- A.算子相邻且输出形状一致← 正确答案
- B.中间结果只被一个算子使用← 正确答案
- C.融合后保持数值等价性← 正确答案
- D.两个算子间存在分支依赖
答案:ABC。融合候选必须相邻、形状匹配、中间结果无其他消费者、数值等价。如果中间结果被多个分支使用,融合会导致重复计算或破坏数据流,因此 D 是反例。
Q7. 关于融合后加速比 S=T_未融合/T_融合 的说法,正确的是?
- A.S 大于 1 时融合一定可部署
- B.S 接近 1 时仍需评估稳定性← 正确答案
- C.S 越小代表融合收益越大
- D.S 与访存带宽完全无关
答案:B。S>1 只说明平均延迟下降,还需结合 p99、内存占用与硬件适配判断是否可部署;S 接近 1 时收益可忽略,要评估波动。S 越小收益越小,而访存带宽正是决定 S 的核心因素之一。
Q8. MatMul-Add 融合避免了哪些开销?
- A.中间矩阵的写回显存← 正确答案
- B.中间矩阵的读回计算← 正确答案
- C.Add 算子的内核启动← 正确答案
- D.矩阵乘法的计算总量
答案:ABC。融合把 bias 放进累加器初值,A×B 的中间矩阵从未写回显存,也就无需读回,Add 内核整体消失。但矩阵乘本身的乘加运算量一个都不少,D 错误。
Q9. 编译器自动融合时,代价模型通常考虑哪些因素?
- A.内核启动时间开销← 正确答案
- B.访存数据总量大小← 正确答案
- C.硬件峰值算力与带宽← 正确答案
- D.模型训练时的损失值
答案:ABC。代价模型用启动开销、FLOPs/峰值算力、Bytes/带宽三者估算内核耗时,判断融合是否值得。训练损失是训练阶段的概念,与推理期图优化无关。
Q10. 判断某算子是访存密集型并适合融合,最佳判据是?
- A.卷积核尺寸是否大于三
- B.算术强度远低于硬件平衡点← 正确答案
- C.输入输出张量是否超过十六
- D.执行时间是否小于一毫秒
答案:B。Roofline 模型告诉我们,算术强度低于硬件平衡点(Peak FLOPs/带宽)时算子受带宽约束,属于访存密集,融合收益大。核尺寸、张量维度、绝对执行时间都是经验碎片,不能作为通用判据。