一.启动流程
Linux下CPU有4个状态:possible,present,online和active,分别对应__cpu_possible_mask,set_cpu_present,__cpu_online_mask和__cpu_active_mask 4个掩码
这4个状态的意义可以查看:https://blog.****.net/liuhangtiant/article/details/84933156
需要补充的是online状态和active的区别;某个核(这里的核指的是逻辑核,如果支持超线,比如8核16线程,此时就有16个逻辑核)在online状态下,只能说明这个核可以跑内核线程,但是不能不能跑用户线程,也就是说,此时SMP不会把用户线程调度到这个核上,通过taskset等绑核操作会报参数错误:
taskset实际上会调用sched_setaffinity函数,taskset会把要绑定的核序号转换成mask,而真正绑定前,sched_setaffinity会检查这个mask是否是__cpu_active_mask4的子集,不是就返回-EINVAL,最终导致上图错误
在online的基础上,如果核也处于active状态,此时SMP是可调度的,同时也可绑核。
二.进程绑核
1.绑核
可在命令行中通过taskset绑定,也可以在程序中通过sched_setaffinity函数绑定;通过这种方式将某个进程绑定到某些核后,其实是限定了SMP对这几个进程的调度范围;单纯绑核而言,可以减少SMP对线程的核间移植,通常可以显著提升单线程性能,但是绑核通常是为了从宏观上对平台做算力均衡;但是其他进程也能用这些核。
2.查看进程当前可以在哪些核上运行
taskset -p <pid>命令会返回该进程的cpus_allowed数值,是一个掩码
三.进程独占
进程独占是在进程绑定基础上不让SMP把其他进程调度到这些独占的核上,另外也不让中断打扰这些核;主要分为三个步骤,可以参考:https://blog.****.net/weixin_30439067/article/details/95622518
四.CPU状态监控
1.sys接口
在/sys目录下,eg. tree /sys/bus/cpu/devices cpu0,可以看到比较详细的cpu信息
2.top命令
top主要是实时查看cpu负载和进程情况,top后按“1”,可以看到各个逻辑核占用情况,绑核和可以通过这种方式看效果:
3.ps命令
ps -ef可以查看父进程
4.cat /proc/cpuinfo
processor是逻辑核编号,core id是物理核编号
5.设备树
这是根文件系统下的设备树木描述文件,和真实设备树文件以及SOC 架构是对应的,可以看到有三个CPU集群,每个集群有两个物理核;这个信息主要是反映当前系统用到的物理核,实际上可能更多,比如下图只用到6个核,但实际有8个核
6.lscpu
主要显示CPU的固有信息,关键字段
Thread(s) per core: 2 :支持超线程,每个核对应两个逻辑核
Byte Order: Little Endian :小端模式
CPU op-mode(s): 32-bit, 64-bit :支持32位和64位
On-line CPU(s) list: 0-15 :对应cpu_online_mask,说明16个逻辑核都是online状态
五.CPU状态配置
1.通过sys接口进行online状态使能
eg. sudo echo "0" > /sys/bus/cpu/devices/cpu0/online ,这条命令让cpu0退出online状态;
默认都开启:
执行这条命令后:
2.设置内核启动参数
(1)CPU隔离
上文配置“进程独占”中,/ boot/grub/grub.conf的kernel列最末尾加上isolcpus=x,y,… (代表将CPUx CPUy隔离),这样,init进程及后续进程的cpus_allowed就不包含这些隔离的CPU了,但是这些CPU仍然是active状态,也就是可以绑核,只是默认不用
(2)中断隔离
被隔离的CPU虽然没有线程run在上面,但是仍会收到interrupt.
Interrupt request是硬件级别的服务请求.详情见附录,此处不表.我们需要知道的是IRQ有一个亲和度属性smp_affinity. smp_affinity决定允许哪些CPU核心处理IRQ.
在redhat(其它发行版未知)中,某一特定IRQ的亲和度值储存在/proc/irq/IRP_NUMBER/smp_affinity文件中.此文件仅ROOT用户可见.储存的值是一个十六进制位掩码(hexadecimal bit-mask),代表着系统的所有CPU核心.
命令cat /proc/interrupts可以看到所有设备的interrupts信息,第一列即为IRP_NUMBER.
命令cat /proc/irq/32/smp_affinity可以看到IRQ号为32的亲和度.默认值为f,代表这个IRP能被所有CPU接受处理.
命令echo 1 >/proc/irq/32/smp_affinity把IRQ号为32的亲和度值设为1,代表这个IRP仅能被CPU0接受处理
照此,我们可以据要求任意绑定IRQ到CPU
虽然我们已经做了很大努力,但是仍有一部分中断没有被绑定,例如: Single function call interrupts, Local timer interrupts等等
3.配置内核
比如在menuconfig中配置后从新编译内核