CPU性能优化:CPU绑定与隔离、中断负载均衡、调度策略选择、降低上下文切换
各位好,我是老张。今天咱们聊聊CPU性能优化这块硬骨头。
说实话,我早年做驱动适配时,最头疼的就是CPU资源打架。你想想看,一个中断来了,把正在跑的关键任务给打断了,系统响应直接崩掉。后来我慢慢摸索出几招,今天全部分享给你们。
核心思路:CPU优化的本质,就是让每个CPU核心干它最擅长的事,别互相干扰。
一、CPU绑定与隔离
CPU绑定,说白了就是把某个进程或线程,死死摁在某个CPU核心上跑。为什么要这么做?
我遇到过这样一个案例:一个实时性要求很高的数据采集任务,默认情况下它在各个核心间跳来跳去。每次切换,缓存就失效了,性能直接打七折。绑核之后,缓存命中率上来了,延迟降了一半。
具体怎么做?Linux下用 taskset 命令:
# 把进程PID 1234绑定到CPU 0-3
taskset -cp 0-3 1234
# 启动时直接绑定
taskset -c 0 ./my_app
代码里也能做,用 sched_setaffinity 系统调用:
#include <sched.h>
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask); // 绑定到CPU 0
sched_setaffinity(0, sizeof(mask), &mask);
我的习惯:关键实时任务绑到独立核心,非关键任务丢到共享核心池。别把所有鸡蛋放一个篮子里。
CPU隔离就更狠了。把某些核心从内核调度器中摘出来,普通进程根本看不到它们。只有你指定的任务才能用。
内核启动参数里加 isolcpus=2,3,核心2和3就被隔离了。然后你用 taskset 把专属任务绑上去,完美。
我曾经踩过的坑:隔离了核心,但忘了把内核线程也迁走。结果内核线程还在隔离核心上跑,白忙活一场。记得用 cset shield 工具把内核线程也赶走。
二、中断负载均衡
中断这玩意儿,处理不好就是性能杀手。你想想,网卡每收一个包就触发一次中断,如果所有中断都挤在CPU 0上,它不得累死?
Linux内核有个 irqbalance 服务,默认会帮你把中断分散到各个核心。但说实话,自动的往往不是最优的。
我建议手动分配。先看看中断号:
cat /proc/interrupts
找到网卡的中断号,比如 eth0 对应中断号 48。然后写它的亲和性:
echo 2 > /proc/irq/48/smp_affinity
这里的 2 是二进制 0010,表示绑定到CPU 1。每个bit代表一个核心。
| 中断类型 | 推荐绑核策略 |
|---|---|
| 网卡RX/TX | 分散到多个核心,避免单核瓶颈 |
| 存储设备 | 绑定到与驱动亲和的核心 |
| 定时器中断 | 留给CPU 0,别动它 |
我的经验:高吞吐网卡场景,用 RPS/RFS 配合中断绑核,效果拔群。RPS把软中断也分散了,RFS还能保证数据局部性。
三、调度策略选择
Linux调度策略有好几种,选错了就是灾难。
- SCHED_OTHER (CFS): 默认策略,公平分享CPU。适合普通应用。
- SCHED_FIFO: 实时策略,先到先服务。优先级高的任务不跑完,低优先级别想动。
- SCHED_RR: 实时策略,时间片轮转。同优先级任务轮流跑。
- SCHED_DEADLINE: 最新策略,指定截止时间。适合硬实时场景。
我一般这么选:
# 把音频播放进程设为SCHED_FIFO,优先级80
chrt -f -p 80 1234
# 代码里设置
struct sched_param param;
param.sched_priority = 80;
sched_setscheduler(0, SCHED_FIFO, ¶m);
注意:实时策略用不好会锁死系统。我曾经把某个死循环进程设成SCHED_FIFO最高优先级,结果系统直接卡死,只能硬重启。实时策略只给那些确定能快速完成的任务用。
四、降低上下文切换
上下文切换,说白了就是CPU从跑A任务切换到跑B任务。每次切换都要保存恢复寄存器、刷新TLB,开销不小。
怎么降?我总结了三条路:
- 减少线程数: 别动不动就开几十个线程。用线程池,控制并发数。
- 使用大页内存: TLB miss少了,切换代价也小了。
- 避免锁竞争: 锁争抢会导致大量上下文切换。用无锁数据结构或者RCU。
看看上下文切换频率:
vmstat 1 5
# 看 cs 列,就是每秒上下文切换次数
如果 cs 值超过几万,说明有问题了。我见过一个数据库服务,cs飙到20万,查了半天发现是日志打印太频繁,每次打印都触发系统调用。改成批量写入后,cs直接降到5000。
避坑指南:我曾经用 perf sched record 抓调度事件,发现某个锁导致大量切换。改用 futex 优化后,性能提升30%。工具用起来,别瞎猜。
知识体系总览
下面这张图,是我自己整理的CPU优化知识框架。你们可以照着这个思路去排查问题:
好了,CPU优化这块就聊到这儿。记住一个原则:让每个核心专注做自己的事,别瞎折腾。 你按照这个思路去调,性能至少能提20%。
想要更多资料,联系可可