KVM虚拟化学习之路(二): cpu超线程与cpu过载

随笔,kvm 2017-04-21

逻辑CPU个数

cat /proc/cpuinfo | grep "processor" | wc -l

物理CPU个数

cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l

每个物理CPU上Core的个数(未计入超线程)

core_per_phy_cpu = $(cat /proc/cpuinfo | grep "core id" | sort | uniq | wc -l)
echo $core_per_phy_cpu

每个物理CPU中逻辑CPU(可能是core,threads或both)的个数

logical_core_per_phy_cpu = $(cat /proc/cpuinfo | grep "siblings" | sort | uniq | awk -F: '{print $2}')
echo $logical_core_per_phy_cpu

判断是否打开超线程的方法: 如果同一个物理CPU上某两个逻辑CPU具有相同的"core id",那么超线程是打开的。所以只要判断 core_per_phy_cpulogical_core_per_phy_cpu 的值就可以了

查看qemu进程和线程

smp是对称多处理系统的意思,多数cpu都支持多核或超线程。 -smp 8 表示分配8个虚拟CPU给客户机。

# ps -efL | grep qemu

qemu      7047     1  7047  0    9 16:13 ?        00:00:06 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7049  0    9 16:13 ?        00:00:00 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7050  0    9 16:13 ?        00:00:00 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7051  0    9 16:13 ?        00:00:00 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7053  1    9 16:13 ?        00:01:01 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7054  0    9 16:13 ?        00:00:16 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7055  0    9 16:13 ?        00:00:11 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7056  0    9 16:13 ?        00:00:13 /usr/bin/kvm -name guest=kvm-22 -smp 4
qemu      7047     1  7058  0    9 16:13 ?        00:00:00 /usr/bin/kvm -name guest=kvm-22 -smp 4

可以得出,PID为7047的进程是qemu启动客户机的进程,它产生了(ID为7049~7058,不一定连续) 作为客户机的8个vCPU在运行。 如果要对客户机进行热拔插,需要加上 maxcpus=num/usr/bin/kvm -smp 8,maxcpus=12 /xx/x.img

CPU过载使用

比如拥有4个逻辑,同时运行了多于4个(如8个,16个)客户机,其中每个客户机分配一个vCPU,这时宿主就会负载。

推荐的做法是对于多个单CPU客户机使用 over-commit 。这时宿主linux对每个客户机的调度十分有效,并不会带来客户机的性能损失。

创建客户机时最不推荐某个客户机的vCPU数量超过物理系统存在的CPU数量,但性能可能反而会比分配较少cpu还差。尽管kvm允许这样的设置。

CPU模型

查看当前qemu支持的所有CPU模型:

# /usr/bin/kvm -cpu ?

x86           qemu64  QEMU Virtual CPU version 2.5+                   
x86           phenom  AMD Phenom(tm) 9550 Quad-Core Processor         
x86         core2duo  Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz 
x86            kvm64  Common KVM processor                            
x86           qemu32  QEMU Virtual CPU version 2.5+                   
x86            kvm32  Common 32-bit KVM processor                     
x86          coreduo  Genuine Intel(R) CPU           T2600  @ 2.16GHz 
x86              486                                                  
x86          pentium                                                  
x86         pentium2                                                  
x86         pentium3                                                  
x86           athlon  QEMU Virtual CPU version 2.5+                   
x86             n270  Intel(R) Atom(TM) CPU N270   @ 1.60GHz          
x86      cpu64-rhel6  QEMU Virtual CPU version (cpu64-rhel6)          
x86           Conroe  Intel Celeron_4x0 (Conroe/Merom Class Core 2)   
x86           Penryn  Intel Core 2 Duo P9xxx (Penryn Class Core 2)    
x86          Nehalem  Intel Core i7 9xx (Nehalem Class Core i7) 
......

第二列中的 qemu64, kvm32, core2duo 等CPU模型qemu命令中原生自带的,支持的模型定义都放在target-i386/cpu.c 文件中

进程的处理器亲和性和vCPU绑定

在smp系统中,linux内核的进程调度器根据自己的策略将系统中的一个进程调度到某个CPU上执行。一个进程在前一个执行时间在cpuM(M为某CPU的id)上运行,而后一个执行时间在cpuN上。

进程的处理器亲和性,即CPU的绑定设置,就是将进程绑定要指定的一个或多个CPU,从而不允许将进程调度到其他CPU上。这样做会破坏原有smp系统各个cpu的负载均衡。

执行ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu -e表示用于所有进程,-L表示参数用于所有线程,-o表示显示以用户自定义的格式输出。 psr表示当前分配给进程的处理器编号,lwp表示线程的ID,args表示运行的命令及其参数,ruser表示运行进程的用户,pid表示进程的ID,ppid表示父进程。

每个vCPU都是宿主机中一个普通的qemu进程,可以使用 taskset 工具对其设置处理器亲和性。

taskset的语法是 taskset -p [mark] pid 。其中mask是一个代表了处理器亲和性的掩码数字,转为二进制从最低位到最高位代表了第一个逻辑CPU到最后一个逻辑CPU。如: taskset -p 0x4 7049


本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

赏个馒头吧