如何实现CPU单核睿频?
之前的Blog:再谈CPU的电源管理(如何做到稳定全核睿频?)最终通过了tuned
实现了CPU全核心运行在允许的全核睿频频率上。但是这个只是场景之一,并不是所有场景下都会用到很多的核心,从这些应用角度讲,更需要少量但是更高频率的核心,一个比较简单的例子就是DPDK,作为DPDK应用,一般来说也不会用到很多核心,但是他的polling模型,是希望单核频率越高越好的。针对类似的这种场景,实现少量核心,比如说单核的高频,比多核全开,频率变低更合适。
那么问题来了,怎么在Linux上实现稳定的单核睿频呢?这里给一个稍微暴力点的办法。
以我们目前机器上的CPUIntel 6240R
为例,在Intel Ark 上,可以看到这款CPU的最大睿频频率是4.00 GHz
,也就是说,理论上,至少有一个核心能运行在4GHz的频率上。虽然Intel没有明确说明这款CPU的全核睿频速度,但是从上次的结果看,这块CPU在全核状态,最高能达到3.2GHz的频率。
那么怎么实现单核最高频率呢?同样上一篇Blog里,在Intel论坛上有个关于C6状态的信息:”has 133 microsecond wakeup latency and turns off core (allowing more power to other cores)”,也就是说,当一个核心进入C6状态,核心就被关闭,同时也意味着有更多的电力可以给其他核心(提升频率)。
这么说就简单了,想办法让不需要的CPU核心进入C6状态,或者将核心关闭就行。这里Linux提供了一个接口,直接关闭CPU,那么理论上关闭了一些核心之后,相应的剩下的核心频率会相应提高。首先,先看看当前CPU的一些情况:
~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 96
On-line CPU(s) list: 0-95
Thread(s) per core: 2
Core(s) per socket: 24
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Model name: Intel(R) Xeon(R) Gold 6240R CPU @ 2.40GHz
Stepping: 7
CPU MHz: 3199.951
CPU max MHz: 4000.0000
CPU min MHz: 1000.0000
BogoMIPS: 4800.00
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
L3 cache: 36608K
NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94
NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95
可以看到目前机器上有两颗CPU,对应的核心分别是0,2,4,6...
双数核,和1,3,5,7...
单数核,如果我想只保留第二颗CPU的1号核心的话,就需要执行:
for i in 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95; do echo 0 > /sys/devices/system/cpu/cpu$i/online ;done
把所有除1之外的单数核心online
状态修改成0,也就是强制这些CPU核心下线。执行之后再执行lscpu
看下状态:
~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 96
On-line CPU(s) list: 0-2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94
Off-line CPU(s) list: 3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95
Thread(s) per core: 1
Core(s) per socket: 12
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Model name: Intel(R) Xeon(R) Gold 6240R CPU @ 2.40GHz
Stepping: 7
CPU MHz: 3199.804
CPU max MHz: 4000.0000
CPU min MHz: 1000.0000
BogoMIPS: 4800.00
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
L3 cache: 36608K
NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94
NUMA node1 CPU(s): 1
可以看到Off-line CPU(s) list:
多了刚刚设置offline的核心。此时第二颗CPU只有第一个核心在线了。此时再运行一下turbostat看下核心频率:
~]# turbostat
Package Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI POLL C1 C1E C6 POLL% C1% C1E% C6% CPU%c1 CPU%c6 CoreTmp PkgTmp PkgWatt RAMWatt PKG_%R
AM_%
- - - 13 0.42 3200 2346 13230 0 26 19085 0 0 0.04 97.55 0.00 0.00 99.58 0.00 58 56 38.96 43.47 0.00 0
.00
0 0 1 67 1.68 4000 2394 978 0 10 1128 0 0 0.00 98.33 0.00 0.00 98.32 0.00 55 56 38.96 43.47 0.00 0
.00
0 0 48 3 0.09 3200 2394 307 0 0 381 0 0 0.00 99.91 0.00 0.00 99.91
0 1 4 15 0.46 3200 2394 613 0 0 985 0 0 0.00 99.55 0.00 0.00 99.54 0.00 56
0 1 52 169 5.30 3200 2394 655 0 0 507 0 0 0.00 94.70 0.00 0.00 94.70
0 2 8 9 0.29 3200 2394 300 0 0 558 0 0 0.00 99.71 0.00 0.00 99.71 0.00 56
0 2 56 5 0.16 3200 2394 183 0 0 214 0 0 0.00 99.84 0.00 0.00 99.84
...
可以看到CPU 1
非常突出,在许多3200中的4000特别亮眼,说明成功的将单核频率拉到了Ark描述的4.0GHz,说明Intel没有骗人,嘿嘿。
到这里任务算是完成了,实际上Intel的睿频状态比较多,不同的核心数量,会获得不一样的频率,具体的,可以根据情况测试。最后还有一件事,就是如何恢复呢,自然也很简单:重启机器,或者反向执行一下脚本:
for i in 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95; do echo 1 > /sys/devices/system/cpu/cpu$i/online ;done