CPU的亲和性, 就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,亲和性是从affinity翻译过来的,应该有点不准确,给人的感觉是亲和性就是有倾向的意思,而实际上是倒向的意思,称为CPU关联性更好,程序员的土话就是绑定CPU,绑核。

多核运行的机器上,每个CPU本身自己会有缓存,缓存着进程使用的信息,而进程可能会被OS调度到其他CPU上,如此,CPU cache命中率就低了,当绑定CPU后,程序就会一直在指定的cpu跑,不会由操作系统调度到其他CPU上,性能有一定的提高。

另外一种使用绑核考虑就是将重要的业务进程隔离开,对于部分实时进程调度优先级高,可以将其绑定到一个指定核上,既可以保证实时进程的调度,也可以避免其他CPU上进程被该实时进程干扰。

1.CPU亲和性在用户态的使用

linux的CPU亲和性在用户态表现为一个cpu_set_t掩码的形式,用户可以调用两个函数设置和获取掩码:

sched_setaffinity是设置指定pid亲和性掩码的,mask是传入的参数;sched_getaffinity则是获取指定pid亲和性掩码的,mask是获取的参数。

cpusetsize可以通过sizeof cpu_set_t算出来。

cpu_set_t 是一个掩码数组,一共有1024位,每一位都可以对应一个cpu核心,以下宏,都是对这个掩码进行操作的。如果需要,一个进程是可以绑定多个cpu的。

而mask的表现是如此的:如果是0X23,转换成二进制则为00100011,则表明进程绑定在0核、1核和5核上。

绑核需要注意是,子进程会继承父进程的绑核关系。

代码实例:

执行之后根据打印和/proc stat的内容可以判断,status有

Cpus_allowed: 08
Cpus_allowed_list: 3

可以更清楚的看到进程绑核状态

但是如果进程已经在运行过程中,用户不能直接改动代码,就用taskset工具更改CPU亲和性关系。

taskset [options] -p [mask] pid

其中mask前面已说了,参看man手册更详细一点。

二、CPU亲和性在内核态机制

在内核进程结构体task_struct里面有一个参数,即为

cpumask_t cpus_allowed;

用来记住CPU的绑核关系。

内核尤其是调度的时候,可以保证让task不会被调度到其他CPU上

进程在选择CPU队列的时候,只选择被允许的CPU队列,使用cpumask_test_cpu进行测试。


CPU亲和性的使用与机制来自于OenHan

链接为:http://oenhan.com/cpu-affinity

发表评论