一、算子性能全景概览
大家好,我是老张。今天咱们聊聊算子性能优化这件事。
说实话,我入行那会儿,大家写算子就是「能跑就行」。后来模型越来越大,数据越来越多,性能问题才真正浮出水面。我记得第一次被老板叫去优化一个卷积算子,跑一次推理要 3 秒多,优化完降到 200 毫秒——那种成就感,嗯,至今难忘。
1.1 什么是算子
算子,说白了就是深度学习网络里的一个基本运算单元。你想想看,一个神经网络模型,无非就是卷积、池化、激活、矩阵乘法这些操作的组合。每个这样的操作,就是一个算子。
举个例子:
// 一个简单的 ReLU 算子
// 输入:x,输出:max(0, x)
for (int i = 0; i < n; i++) {
y[i] = x[i] > 0 ? x[i] : 0;
}
我在项目中遇到过不少新人,一上来就写这种循环。嗯,代码没错,但性能嘛……咱们后面会讲怎么优化。
核心理解:算子 = 输入数据 + 计算逻辑 + 输出数据。优化算子,就是让这三者配合得更高效。
1.2 算子性能的衡量指标
怎么判断一个算子写得好不好?我个人习惯看三个指标:
延迟(Latency)
延迟就是一次运算从开始到结束的时间。单位通常是毫秒或微秒。你想想看,用户点一下按钮,等 5 秒才出结果,谁受得了?
我建议把延迟拆开看:
- 计算延迟:CPU/GPU 真正在算的时间
- 访存延迟:数据从内存搬到寄存器的时间
- 调度延迟:线程/任务切换的时间
吞吐量(Throughput)
吞吐量是单位时间内能处理多少个请求。比如一个推理服务,每秒能处理 1000 张图片,那吞吐量就是 1000 QPS。
延迟和吞吐量是什么关系?我打个比方:
- 延迟 = 做一道菜的时间
- 吞吐量 = 一小时内能做多少道菜
你缩短做菜时间,吞吐量自然就上去了。但反过来,吞吐量高不一定延迟低——比如你同时开 10 个灶台,每道菜可能反而更慢。
算力利用率(Utilization)
这个指标很多人忽略,但其实很关键。算力利用率 = 实际计算量 / 理论峰值计算量。
举个例子:
| 硬件 | 理论峰值 | 实际达到 | 利用率 |
|---|---|---|---|
| NVIDIA A100 | 312 TFLOPS | 250 TFLOPS | 80% |
| 你的算子 | 312 TFLOPS | 30 TFLOPS | 9.6% |
我曾经优化过一个算子,利用率只有 5%。说白了,硬件在「摸鱼」。后来通过调整数据排布和循环顺序,利用率提到了 60% 以上。
我的经验:先看利用率,再看延迟。利用率低,说明优化空间大;利用率已经很高了,那就得从算法层面想办法。
1.3 影响算子性能的关键因素
影响算子性能的因素很多,但归根结底就三个:计算、访存、调度。
计算(Compute)
计算就是 CPU/GPU 真正在「算」的那部分。比如矩阵乘法、卷积运算。
影响计算性能的因素:
- 算法复杂度:O(n²) 和 O(n log n) 差很多
- 指令集:AVX、NEON、Tensor Core 这些能用就用
- 数据精度:FP32 和 FP16 的计算速度差一倍
我记得有一次优化一个矩阵乘法算子,用 AVX2 指令集重写后,速度提升了 4 倍。嗯,指令集的力量。
访存(Memory Access)
访存往往是最大的瓶颈。为什么?因为 CPU 算得越来越快,但内存速度没跟上。
你想想看:
- CPU 一级缓存访问:1 纳秒
- 内存访问:100 纳秒
- 差了 100 倍!
所以优化访存,核心就是让数据尽量待在缓存里。我常用的方法:
- 数据局部性:访问连续内存,别跳来跳去
- 数据排布:NCHW 还是 NHWC?选对了差很多
- 预取:提前告诉 CPU 要加载哪些数据
避坑指南:我曾经花了两周优化计算逻辑,结果发现瓶颈在访存。白忙活一场。所以先做 profiling,找到真正的瓶颈再动手。
调度(Scheduling)
调度就是怎么安排计算任务。多线程、多核、GPU 的 warp 调度,都属于调度范畴。
影响调度性能的因素:
- 任务粒度:任务太大,负载不均;任务太小,调度开销大
- 依赖关系:有依赖的任务只能串行
- 资源竞争:多个线程抢同一个资源,性能就下降
我建议这样思考:
- 先看能不能并行
- 再看怎么分任务
- 最后看怎么减少竞争
知识体系总览
下面这张图,是我自己总结的算子性能优化知识体系。你把它记在心里,后面每一章都会围绕它展开。
这张图展示了算子性能优化的核心框架。三个关键因素——计算、访存、调度——共同决定了算子的性能。而延迟、吞吐量、算力利用率,就是衡量优化效果的三把尺子。
后面的章节,我会逐一深入讲解每个因素怎么优化。嗯,咱们慢慢来。
我的建议:刚开始做算子优化,别想着一步到位。先跑 profiling,找到瓶颈,然后针对性地优化。一次只改一个地方,看看效果。这样积累经验,慢慢就有感觉了。