CPU调度实验
实验目标
通过实际编程和系统工具观测,深入理解CPU调度和上下文切换的工作机制。
实验环境要求
- Linux系统(Ubuntu 20.04+推荐)
- gcc编译器
- sysstat工具包(提供pidstat、vmstat等命令)
安装依赖
sudo apt update
sudo apt install -y build-essential sysstat
实验列表
实验1:上下文切换观测
目标: 观察大量线程导致的上下文切换
步骤:
- 编译测试程序:
gcc -o context_switch_test context_switch_test.c -lpthread
- 在一个终端运行程序:
./context_switch_test
- 在另一个终端观测上下文切换:
# 观测系统级上下文切换
vmstat 1
# 观测进程级上下文切换
pidstat -w 1
- 分析输出:
- vmstat中的
cs
列显示每秒上下文切换次数 - pidstat中的
cswch/s
显示自愿切换,nvcswch/s
显示非自愿切换 - 高的
nvcswch/s
表示CPU竞争激烈
- vmstat中的
预期结果:
- cs值显著增加(可能达到数千/秒)
- CPU使用率接近100%
- 系统响应可能变慢
实验2:调度参数调优
目标: 理解调度参数对性能的影响
步骤:
- 查看当前调度参数:
cat /proc/sys/kernel/sched_latency_ns
cat /proc/sys/kernel/sched_min_granularity_ns
- 运行基准测试:
time ./context_switch_test
- 调整调度参数:
# 增大最小时间片(减少上下文切换)
sudo sysctl -w kernel.sched_min_granularity_ns=3000000 # 3ms
# 增大调度延迟
sudo sysctl -w kernel.sched_latency_ns=12000000 # 12ms
- 再次运行基准测试:
time ./context_switch_test
- 对比结果:
- 执行时间是否变化
- 上下文切换次数是否减少
- CPU利用率的变化
实验3:进程优先级实验
目标: 理解nice值对调度的影响
步骤:
- 创建CPU密集型程序(如果还没有):
// cpu_intensive.c
#include <stdio.h>
#include <unistd.h>
int main() {
int i = 0;
while (1) {
i++;
if (i % 100000000 == 0) {
printf("PID %d: iteration %d\n", getpid(), i);
}
}
return 0;
}
- 编译:
gcc -o cpu_intensive cpu_intensive.c
- 以不同优先级运行:
# 终端1:高优先级(-20)
sudo nice -n -20 ./cpu_intensive &
# 终端2:低优先级(+19)
nice -n 19 ./cpu_intensive &
# 终端3:观测进程状态
top -H
- 分析结果:
- 观察两个进程的CPU使用率差异
- 查看进程的NI(nice)值和PRI(优先级)
- 理解优先级如何影响CPU时间分配
清理实验环境
# 杀死所有测试进程
pkill -f context_switch_test
pkill -f cpu_intensive
# 恢复默认调度参数
sudo sysctl -w kernel.sched_min_granularity_ns=750000
sudo sysctl -w kernel.sched_latency_ns=6000000
扩展练习
多核调度实验:修改程序,让线程绑定到不同的CPU核心,观察调度行为的变化。
实时调度实验:使用
SCHED_FIFO
或SCHED_RR
策略,对比与默认SCHED_OTHER
的差异。性能分析:使用perf工具生成调度火焰图:
sudo perf sched record -- ./context_switch_test
sudo perf sched latency
注意事项
- 某些操作需要root权限
- 实验可能导致系统负载较高
- 建议在测试环境或虚拟机中进行
- 实验结束后记得清理进程和恢复系统参数