真实面经题目 · 原创解析
GPU 推理中 depthwise / separable convolution 为什么可能变慢,为什么常被判断为访存密集型算子?
这题考 GPU 推理中 depthwise / separable convolution 为什么容易 memory-bound。它虽然显著降低 FLOPs,但 activation 读写没有同比减少,算术强度低,无法充分利用 GPU 计算吞吐,瓶颈常转向显存带宽、cache locality 和 kernel launch。
真实面经题目 · 原创解析
这题考 GPU 推理中 depthwise / separable convolution 为什么容易 memory-bound。它虽然显著降低 FLOPs,但 activation 读写没有同比减少,算术强度低,无法充分利用 GPU 计算吞吐,瓶颈常转向显存带宽、cache locality 和 kernel launch。
Depthwise convolution 在理论 FLOPs 上比普通卷积低很多,因为每个输入通道只和自己的 depthwise kernel 计算,不做跨通道累加。但在 GPU 推理里,FLOPs 少不一定更快。它仍然要读取 input feature map、读取权重、写输出,而且每个输出元素只做很少乘加,算术强度很低。GPU 计算单元很强,如果每次从显存搬一批数据只做很少运算,就会被内存带宽限制,表现为 memory-bound。Separable convolution 通常还接 1x1 pointwise convolution,真实耗时可能转移到 pointwise;depthwise 部分则因为跨通道复用弱、线程粒度小、访存不连续和 kernel launch 开销明显,实际加速可能远低于 FLOPs 降幅。
普通卷积会把每个输出通道和所有输入通道做累加,既有空间计算也有通道混合。Depthwise convolution 每个输入通道单独卷积,通道之间不混合;depthwise separable convolution 再接 1x1 pointwise 完成通道混合。
普通卷积 FLOPs 高,但输入和权重可以被多个输出通道复用,矩阵化后能更好利用 Tensor Core 或 CUDA core。Depthwise 每个输出元素只做少量乘加,但仍要读写 activation,内存访问占比高,因此速度不按 FLOPs 等比例下降。
Depthwise 通常权重很小,真正占带宽的是 input/output activation。由于跨通道复用弱,线程组织不当时会出现非合并访存、cache 命中差、occupancy 不足或每个 block 有效计算太少。profiling 可能看到 SM 利用率不高而 DRAM bandwidth 接近瓶颈。
优化不是盲目减少乘法,而是减少中间结果写回和提升数据复用。常见手段包括融合 depthwise、bias、BN、activation,选择适合硬件的 NHWC/NCHW 布局,向量化 load/store,使用寄存器或 shared memory 改善局部性,减少小 batch kernel launch 开销。
可以用 roofline model 分析算术强度:FLOPs 除以字节访问量,如果落在内存带宽限制区域,说明优化计算单元收益有限。实际还要看 dram throughput、L2 hit rate、SM occupancy、achieved FLOPs 和 kernel duration。
因为 latency 还受显存带宽、cache 命中、kernel launch、数据布局和硬件利用率影响。depthwise 计算少但读写 activation 不少,常常从 compute-bound 变成 memory-bound。
计算算术强度 FLOPs/byte,再结合目标 GPU 的峰值带宽和峰值算力。如果点落在带宽斜线限制区,优先优化访存;如果接近算力平台,才优先优化计算。
不同布局影响连续访存、向量化和库 kernel 支持。某些 GPU depthwise kernel 对 NHWC 更友好,能让同一像素的通道数据更连续;但实际要以目标硬件和框架 benchmark 为准。
pointwise 1x1 通常承担更多 FLOPs,可能成为 compute-heavy 部分;depthwise FLOPs 少但 memory-bound 明显。端到端要看两者耗时和中间 activation 写回成本。