什么是绑核
所谓绑核,其实就是设定某个进程/线程与某个CPU核的亲和力(affinity)。
设定以后,Linux调度器就会让这个进程/线程只在所绑定的核上面去运行。但并不是说该进程/线程就独占这个CPU的核,其他的进程/线程还是可以在这个核上面运行的。
如果想要实现某个进程/线程独占某个核,就要使用cpuset命令去实现。
其实,很多情况下,为了提高性能,Linux调度器会自动实现尽量让某个进程/线程在同样的CPU上去运行。所以,除非必须,我们没有必要显式的去进行进程绑核操作(虚拟机中有时候需要这样做)。
绑核之前 ,
在Linux内核启动的命令行加上"isolcpus="参数,可以实现CPU的隔离,使得在系统启动后普通进程默认都不会调度到被隔离的CPU上执行
例如,隔离了cpu2和cpu3的grub的配置文件如下:
ps -efL psr|grep 0
ps -efL psr|grep 1
ps -efL psr|grep 2
ps -efL psr|grep 3
查看隔离是否成功,如果隔离成功过,2和3两个核上仅有如下几个进程:
migration进程(用于
进程在不同
CPU
间迁移
)
两个kworker进程(用于
处理
workqueues
)
ksoftirqd进程(用于
调度
CPU
软中断的进程
)
这些进程都是内核对各个
CPU
的一些守护进程,没有其他的普通进程在
cup2
和
cpu3
上运行,说明对它们的隔离是生效的
然后在宿主机中进行如下操作
taskset用于将某个进程/线程绑定到CPU的某个或某几个核上面,其用法如下:
taskset -p PID #查出进程pid现在的绑核情况。
设置绑核有两种方法:
掩码形式
列表形式
注意:下面的绑核实际绑定的逻辑cpu,按照逻辑cpu的id进行绑定(启用超线程时一定要注意)!!!!!
1、掩码形式绑核
将掩码转换为二进制形式,从最低位到最高位代表物理CPU的#0、#1、……、#n号核。某位的值为0表示不绑该核,1表示绑。
比如:
0x00000001的二进制为0000...0001,只有第0号核的位置是1,所以表示只绑0号核;
0x00000003的二进制为0000...0011,第0和1号核的位置是1,所以表示绑CPU的0号和1号核;
0xFFFFFFFF的二进制为1111...1111,所有32个核的位置都为1,所以表示绑CPU的0~31核。
需要注意的是,并非掩码中给出的CPU核就一定会存在,比如0x00000400(二进制为100 0000 0000)理论上代表CPU的第10号核,
但是该核在真正的计算机上面并不一定是存在的。而且,如果我们试图将物理上并不存的核绑定给某个进程时,会返回错误。
掩码形式的绑核命令为:
taskset -p MASK PID #mask要使用带0x前缀的16进制数
2、列表形式
列表形式指直接指定要绑的CPU核的列表,列表中可以有一个或多个核。
具体语法如下:
taskset -cp cpu-list PID #cpu-list是数字化的cpu列表,从0开始。多个不连续的cpu可用逗号连接,连续的可用短现连接,比如0,2,5-11等。
比如:
taskset -cp 0,2,5-11 10258 #将进程10258绑定到#0、#2、#5~#11号核上面
注意:只要taskset成功返回了,那就表示绑核一定成功了,即该进程已被绑到指定的核上面,而且taskset命令会显示原来的绑核(原来的可能是系统默认分配的核)情况,以及新的绑核情况。