1. 前言
最近进行性能测试时发现,相同计算量的情况下不同时刻程序的CPU占用量会偏移很大,比如在30%-50%之间浮动。在对前后两个版本进行性能优化时,这种浮动带来了很大的困扰。仔细思考程序逻辑,按道理不应该会出现这样的性能浮动,通过搜索资料发现,可能有以下因素影响了CPU占用率。
- 动态调频技术,动态调频+睿频等技术造成CPU的频率不是固定值,所以同样的程序同样的计算量情况下在不同时刻表现得CPU占用率会有较大得差异。
- 超线程技术,超线程让两个线程公用一个物理核,当两个线程都进行计算型任务时,会相互影响,导致两个线程得CPU占用率都升高。
除此之外,还有一些其他因素会影响CPU利用率,比如CPU亲和性/进程的优先级等,可进一步参考:减少CPU测量噪声
本文介绍如何消除CPU频率变化和超线程对进程CPU性能测量的影响,即:固定CPU频率+关闭超线程
2. 如何固定CPU频率
windows下固定CPU频率,参考:【电脑优化】win10、win11限制cpu处理器最大频率
Linux下固定CPU频率,以笔者Thinkpad X13安装Ubuntu 20.04版本为例:
2.1 关闭睿频
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver #查看当前的驱动,笔者驱动时acpi-cpufreq,后续步骤仅对此驱动有效
cat /sys/devices/system/cpu/cpufreq/boost # 查看是否开启了睿频,如果输出为1则说明已启用睿频
echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost #临时禁用睿频
2.2 固定频率
2.2.1 安装cpufrequils
终端输入命令行安装cpu频率调控软件
sudo apt-get install cpufrequtils
2.2.2 查看CPU信息
- 查看硬件信息
cat /proc/cpuinfo
笔者CPU为Intel® Core™ i5-10210U CPU @ 1.60GHz,4核8线程,基准频率1.6GHz
- 查看CPU频率控制器信息
cpufreq-info
执行上述命令会输出各个逻辑CPU的信息:
analyzing CPU 0: # 0号CPU
driver: acpi-cpufreq # 控制CPU频率的驱动
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0 maximum transition latency: 10.0 us. hardware limits: 400 MHz - 2.10 GHz # 硬件CPU频率范围
#可选的CPU频率
available frequency steps: 2.10 GHz, 2.10 GHz, 2.00 GHz, 1.90 GHz, 1.70 GHz, 1.60 GHz, 1.50 GHz, 1.40 GHz, 1.20 GHz, 1.10 GHz, 1000 MHz, 800 MHz, 700 MHz, 600 MHz, 500 MHz, 400 MHz
#可选的CPU频率控制器
available cpufreq governors: conservative, ondemand, userspace, powersave, performance, schedutil
#当前的策略是CPU会在400MHz到1.6GHz之间浮动,具体取决于ondemand的控制器
current policy: frequency should be within 400 MHz and 1.60 GHz. The governor "ondemand" may decide which speed to use within this range.
current CPU frequency is 800 MHz (asserted by call to hardware). # 当前的CPU频率
# CPU在各种频率下运行的占比
cpufreq stats: 2.10 GHz:0.93%, 2.10 GHz:0.00%, 2.00 GHz:0.02%, 1.90 GHz:0.06%, 1.70 GHz:0.06%, 1.60 GHz:1.89%, 1.50 GHz:0.73%, 1.40 GHz:0.65%, 1.20 GHz:0.48%, 1.10 GHz:0.32%, 1000 MHz:0.78%, 800 MHz:1.25%, 700 MHz:2.12%, 600 MHz:5.02%, 500 MHz:14.10%, 400 MHz:71.57% (13815)
- 动态观测CPU频率
watch -n 1 "cat /proc/cpuinfo | grep 'MHz'" #观察频率
- 更改频率
cpufreq-set -g userspace #CPU策略设置为用户自定义模式
cpufreq-set -c 0 -f 1600000 #固定为1.6GHz,注意此频率不要超过硬件的基准频率
cpufreq-set -c 1 -f 1600000
cpufreq-set -c 2 -f 1600000
... #有几个CPU就执行多少次
2.2.3 验证结果
此时再观察CPU频率,发现已经固定下来了:
watch -n 1 "cat /proc/cpuinfo | grep 'MHz'"
输出:
Every 1.0s: cat /proc/cpuinfo | grep 'MHz' cpu MHz : 1600.029 cpu MHz :
1600.000 cpu MHz : 1600.000 cpu MHz : 1600.000 cpu MHz : 1600.000 cpu MHz :
1600.000 cpu MHz : 1600.000 cpu MHz : 1600.000
2. 关闭超线程
如果担心超线程会影响CPU占用率,可以进BIOS关闭超线程。但这会造成资源浪费,建议仅在测试场景关闭。
【1】永久关闭: 进BIOS关闭。
【2】临时关闭:参考disable-hyperthreading-from-within-linux-no-access-to-bios
3. 参考
CPU 流水线技术,缓存一致性,缓存命中率及其优化 - 向阳而生的文章 - 知乎
1246

被折叠的 条评论
为什么被折叠?



