Linux 性能实战 | 附录:进程CPU使用率的计算
·
一、核心公式(工程上真正使用的)
进程 CPU 使用率必须是“两个时间点之间的差值”,公式如下:
CPU% = (Δ(utime + stime) / Δtotal_cpu_time) × NCPU × 100%
或更常见等价形式:
CPU% = Δproc_time / Δwall_time × 100%
取决于你用哪种参照系。
下面解释清楚。
二、utime / stime 是什么单位?
单位不是秒,而是:
clock ticks
转换成秒:
seconds = ticks / sysconf(_SC_CLK_TCK)
查看:
getconf CLK_TCK
通常:
100
表示:
1 tick = 10 ms
三、方法 1:最直观工程计算法(推荐)
步骤:
Step 1:读取进程 CPU 时间
cat /proc/<pid>/stat
第 14、15 字段:
utime stime
例如:
第一次:
utime = 1200
stime = 300
total = 1500
1 秒后:
utime = 1300
stime = 400
total = 1700
增量:
Δproc = 200 ticks
Step 2:换算为秒
如果 CLK_TCK = 100:
200 ticks = 2 seconds CPU time
Step 3:除以实际时间
假设采样间隔 1 秒:
CPU% = 2 / 1 × 100% = 200%
表示:
使用了 2 个 CPU 核心满载
四、为什么可以超过 100%?
因为进程可以多线程并行:
1 核满载 = 100%
2 核满载 = 200%
8 核满载 = 800%
top 的显示就是这样。
五、方法 2:用 /proc/stat 作为基准(更精确)
读取:
cat /proc/stat
第一行:
cpu user nice system idle iowait irq softirq steal ...
计算:
total_cpu_time = 所有字段之和
然后:
CPU% = Δproc_time / Δtotal_cpu_time × NCPU × 100%
这是 top 的实现方式。
六、完整 Python 示例(工程级)
import time
CLK_TCK = 100
def read_proc_time(pid):
with open(f"/proc/{pid}/stat") as f:
fields = f.read().split()
utime = int(fields[13])
stime = int(fields[14])
return utime + stime
pid = 1234
t1 = read_proc_time(pid)
time.sleep(1)
t2 = read_proc_time(pid)
delta = t2 - t1
cpu_percent = delta / CLK_TCK * 100
print(cpu_percent, "%")
七、utime vs stime 的工程意义
它们回答不同问题:
| 字段 | 含义 | 判断什么问题 |
|---|---|---|
| utime | 用户态执行时间 | 算法 / 计算 |
| stime | 内核态执行时间 | syscall / IO / kernel |
八、工程诊断意义(非常重要)
情况 1:utime 高
utime >> stime
说明:
CPU 花在用户代码
原因:
- 算法复杂
- 死循环
- 计算密集
情况 2:stime 高
stime >> utime
说明:
CPU 花在内核
原因:
- write()
- read()
- 网络
- 文件系统
- 锁竞争
情况 3:CPU% 低,但进程卡
检查:
D state
说明:
在等 IO
不是 CPU 问题。
九、top 的 %CPU 本质就是这个公式
top 每隔一段时间:
读取 proc stat
计算差值
显示 %
不是瞬时值。
十、一张完整因果链图
十一、一句话工程总结
进程 CPU 使用率,本质是“单位时间内消耗的 CPU 时间”,
utime + stime 提供了这个时间,而 CPU% 是它的变化速率。

更多推荐

所有评论(0)