第一百九十章:性能优化
大乘期涉及内核源码:
一
数据中心的最深处,林小源来到一间密室。密室的墙壁上挂满了火焰图——红色的色块高低起伏,如同燃烧的山峦。
一位精瘦的老者站在火焰图前,手持放大镜,仔细端详着每一处细节。
"前辈在看什么?"
"性能热点。"老者没有回头,"我是性能优化的守护者。perf、ftrace、火焰图——这些工具能告诉你,CPU的时间都花在了哪里。找到热点,才能优化。"
他放下放大镜,转向林小源。"性能优化不是玄学,是科学。第一步,测量;第二步,找到瓶颈;第三步,优化;第四步,再测量。没有测量的优化是盲目的。"
"前辈,有哪些优化手段?"
老者走到一张工作台前,台上摆满了各种工具。"缓存优化——数据对齐到缓存行边界,避免false sharing。分支预测——用likely/unlikely告诉CPU哪条路径更可能执行。内联函数——减少函数调用的开销。"
二
老者拿起一个透明的容器,里面装着一段数据流。"零拷贝。传统的数据传输需要多次拷贝——从磁盘到内核缓冲区,从内核缓冲区到用户空间,再从用户空间到网络缓冲区。sendfile和splice绕过了这些拷贝,让数据直接从文件缓冲区流向网络缓冲区。"
"这能省多少?"
"在高吞吐的网络服务器上,零拷贝可以省掉30%以上的CPU时间。"老者将容器放回台上,"内核中还有许多类似的优化:批处理——把多个操作合并成一次,减少系统调用和中断的开销;延迟处理——中断下半部,把不紧急的工作推迟到稍后处理。"
三
"前辈,SIMD呢?"林小源问道。
老者从抽屉中取出一枚特殊的水晶,水晶中闪烁着四个并排的数字。"SIMD——单指令多数据。一条指令同时处理四个、八个甚至十六个数据。内核中的crypto子系统、网络校验和计算,都用SIMD加速。"
他将水晶举到灯光下。"但SIMD有约束——数据必须对齐,算法必须能向量化。不是所有计算都适合SIMD。"
老者收起水晶,语重心长地说:"性能优化是一门艺术。它需要对硬件的深刻理解,对算法的精准把握,对数据的敏锐嗅觉。记住,过早优化是万恶之源——先让代码正确,再让它快。"
/*
* 内核性能优化:
*
* 1. 缓存优化
* 数据对齐
* 缓存行填充
* 减少缓存颠簸
*
* 2. 分支预测
* likely/unlikely
* 帮助 CPU 预测
*
* 3. 内联函数
* inline
* 减少函数调用开销
*
* 4. Per-CPU 数据
* 避免锁竞争
*
* 5. 批处理
* 减少操作次数
*
* 6. 延迟处理
* 中断下半部
* 工作队列
*
* 7. 零拷贝
* sendfile
* splice
*
* 8. SIMD
* 向量化指令
*/
/* 缓存优化 */
struct __attribute__((aligned(64))) cache_aligned {
int data;
char padding[60]; /* 填充到 64 字节 */
};
/* 分支预测优化 */
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
int process(int val) {
if (likely(val > 0)) {
/* 常见路径 */
return val * 2;
} else {
/* 罕见路径 */
return 0;
}
}
/* 内联函数 */
static inline int fast_add(int a, int b) {
return a + b;
}
printf("=== 性能优化 — 让系统更快 ===\n\n");
/* 缓存优化 */
printf("--- 缓存优化 ---\n");
printf("普通结构体大小: %zu\n", sizeof(int));
printf("缓存对齐结构体大小: %zu\n", sizeof(struct cache_aligned));
printf("缓存行大小: 64 字节\n\n");
/* 分支预测 */
printf("--- 分支预测 ---\n");
int result = process(10);
printf("process(10) = %d\n", result);
printf("likely/unlikely 帮助 CPU 预测\n\n");
/* 内联函数 */
printf("--- 内联函数 ---\n");
int sum = fast_add(3, 4);
printf("fast_add(3, 4) = %d\n", sum);
printf("inline 减少函数调用开销\n\n");
printf("--- 优化技术 ---\n");
printf("1. 缓存优化:\n");
printf(" 数据对齐\n");
printf(" 缓存行填充\n");
printf(" 减少缓存颠簸\n\n");
printf("2. 分支预测:\n");
printf(" likely/unlikely\n");
printf(" 帮助 CPU 预测\n\n");
printf("3. 内联函数:\n");
printf(" inline\n");
printf(" 减少函数调用开销\n\n");
printf("4. Per-CPU 数据:\n");
printf(" 避免锁竞争\n\n");
printf("5. 批处理:\n");
printf(" 减少操作次数\n\n");
printf("6. 延迟处理:\n");
printf(" 中断下半部\n");
printf(" 工作队列\n\n");
printf("7. 零拷贝:\n");
printf(" sendfile\n");
printf(" splice\n\n");
printf("8. SIMD:\n");
printf(" 向量化指令\n");
printf(" 加速计算\n\n");
printf("--- 性能分析工具 ---\n");
printf("perf:\n");
printf(" 性能计数器\n");
printf(" 采样分析\n\n");
printf("ftrace:\n");
printf(" 函数跟踪\n\n");
printf("火焰图:\n");
printf(" 可视化性能热点\n");#include <stdio.h>
#include <time.h>
/*
* 内核性能优化:
*
* 1. 缓存优化
* 数据对齐
* 缓存行填充
* 减少缓存颠簸
*
* 2. 分支预测
* likely/unlikely
* 帮助 CPU 预测
*
* 3. 内联函数
* inline
* 减少函数调用开销
*
* 4. Per-CPU 数据
* 避免锁竞争
*
* 5. 批处理
* 减少操作次数
*
* 6. 延迟处理
* 中断下半部
* 工作队列
*
* 7. 零拷贝
* sendfile
* splice
*
* 8. SIMD
* 向量化指令
*/
/* 缓存优化 */
struct __attribute__((aligned(64))) cache_aligned {
int data;
char padding[60]; /* 填充到 64 字节 */
};
/* 分支预测优化 */
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
int process(int val) {
if (likely(val > 0)) {
/* 常见路径 */
return val * 2;
} else {
/* 罕见路径 */
return 0;
}
}
/* 内联函数 */
static inline int fast_add(int a, int b) {
return a + b;
}
int main() {
printf("=== 性能优化 — 让系统更快 ===\n\n");
/* 缓存优化 */
printf("--- 缓存优化 ---\n");
printf("普通结构体大小: %zu\n", sizeof(int));
printf("缓存对齐结构体大小: %zu\n", sizeof(struct cache_aligned));
printf("缓存行大小: 64 字节\n\n");
/* 分支预测 */
printf("--- 分支预测 ---\n");
int result = process(10);
printf("process(10) = %d\n", result);
printf("likely/unlikely 帮助 CPU 预测\n\n");
/* 内联函数 */
printf("--- 内联函数 ---\n");
int sum = fast_add(3, 4);
printf("fast_add(3, 4) = %d\n", sum);
printf("inline 减少函数调用开销\n\n");
printf("--- 优化技术 ---\n");
printf("1. 缓存优化:\n");
printf(" 数据对齐\n");
printf(" 缓存行填充\n");
printf(" 减少缓存颠簸\n\n");
printf("2. 分支预测:\n");
printf(" likely/unlikely\n");
printf(" 帮助 CPU 预测\n\n");
printf("3. 内联函数:\n");
printf(" inline\n");
printf(" 减少函数调用开销\n\n");
printf("4. Per-CPU 数据:\n");
printf(" 避免锁竞争\n\n");
printf("5. 批处理:\n");
printf(" 减少操作次数\n\n");
printf("6. 延迟处理:\n");
printf(" 中断下半部\n");
printf(" 工作队列\n\n");
printf("7. 零拷贝:\n");
printf(" sendfile\n");
printf(" splice\n\n");
printf("8. SIMD:\n");
printf(" 向量化指令\n");
printf(" 加速计算\n\n");
printf("--- 性能分析工具 ---\n");
printf("perf:\n");
printf(" 性能计数器\n");
printf(" 采样分析\n\n");
printf("ftrace:\n");
printf(" 函数跟踪\n\n");
printf("火焰图:\n");
printf(" 可视化性能热点\n");
return 0;
}道藏笔记
内核启示
性能优化让系统更快更高效。
优化技术:
- 缓存优化 — 数据对齐、缓存行填充
- 分支预测 — likely/unlikely
- 内联函数 — 减少调用开销
- Per-CPU — 避免锁竞争
- 批处理 — 减少操作次数
- 延迟处理 — 中断下半部
- 零拷贝 — sendfile
- SIMD — 向量化指令
性能分析:
- perf — 性能计数器
- ftrace — 函数跟踪
- 火焰图 — 可视化热点
性能优化是艺术——在细节中寻找提升。
性能优化之试
性能优化中,单条指令处理多份数据的向量化技术缩写是什么?