Linux高性能任务独占CPU举例分析

介绍

这篇文章主要讲解了“Linux高性能任务独占CPU举例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux高性能任务独占CPU举例分析”吧!

<强>第1部分工程需求

在一个SMP或者NUMA系统中,CPU的数量大于1。在工程中,我们有时候有一种需求,就是让某个能够独占CPU,这个CPU什么都不做,就只做指定的任务,从而获得低延迟,高实时的好处。

比如在DPDK中,通过设置

 GRUB_CMDLINE_LINUX_DEFAULT=癷solcpus=0 - 3、5、7”

隔离CPU0, 3, 5, 7,让DPDK的任务在运行的时候,其他任务不会和DPDK的任务进行上下文切换,从而保证网络性能最佳[1]。在实时应用场景中,通过isolcpus=2隔离CPU2,然后把实时应用通过taskset绑定到隔离的核:

 taskset-c  2, pn_dev 

从而保证低延迟要求[2]。

<强>第2部分用户态隔离

这个地方,我们可以看的出,它们统一都使用了isolcpus这样一个启动参数。

实践是检验真理的唯一标准、下面我们来启动一个8核的ARM64系统,运行Ubuntu,并指定isolcpus=2这个启动参数:

癓inux高性能任务独占CPU举例分析"

系统启动后,我们运行下面简单的程序(启动8个进程运行而死循环):

癓inux高性能任务独占CPU举例分析"

我们是8核的,现在又是运行8个进程,所以理论上来讲,负载均衡后,8个进程应该均分地运行在8个核上面,但是我们来看看实际的htop结果:

癓inux高性能任务独占CPU举例分析"

我们发现3(也就是CPU2)上面的CPU占用率是0.0%。这实证了CPU2已经被隔离,用户空间的进程不能在它上面跑。

当然,这个时候,我们可以通过taskset,强行把其中的一个。,绑定到CPU2上面去:

癓inux高性能任务独占CPU举例分析"

从上面命令的结果看出,663年原本的亲和力,列表只有0,1,3 - 7是没有2的,而我们强行把它设置为了2,之后再看htop, CPU2上面占用100%:

癓inux高性能任务独占CPU举例分析"

通过上面的实验,我们明显可以看出isolcpus=2使得CPU2上无法再运行用户空间的进程了(除非手动设置亲和力)。

<强>第3部分内核态隔离

<强>中断

但是,能在CPU2上面运行的,不是只有用户态的任务,还可以有内核线程,中断等,那么isolcpus=能否隔离内核线程和中断呢?

对于中断,我们特别容易查看,就是实际去验证每个IRQ的smp_affinity就好了:

癓inux高性能任务独占CPU举例分析"

从上图明显可以看的出,对于44岁47号这种外设的中断,Linux内核把smp_affinity设置为了FB(11111011),明显避开了CPU2,所以,实际外设中断也不会在CPU2发生,除非我们强行给中断绑核,比如让44号中断绑定到CPU2:

 echo  2,祝辞的/proc/IRQ/44/smp_affinity_list 

之后,我们发现44号中断在CPU2可以发生:

癓inux高性能任务独占CPU举例分析"

但是,系统的定时器中断,IPI,由于是Linux系统的运行基石,实际还是要在CPU2上面运行的。这里面最可能给任务带来延迟抖动的,自然是计时器,蜱虫。

下面我们重点探讨下滴答声的问题,由于Linux一般情况下,已经配置闲置状态的NO_HZ,痒,所以CPU2上面什么都不跑的时候,实际定时器中断几乎不发生。

下面,我们还是在isolcpus=2的情况下,运行前面那个8个进程的。,默认情况下没有任务会占用CPU2。通过先后运行几次猫,/proc/中断|头,2,我们会看到其核心的计时器中他断频繁发生,而CPU2几乎不变,这显然是空闲的时候的NO_HZ在发挥省电的作用:

癓inux高性能任务独占CPU举例分析"

但是,一旦我们放任务到CPU2,哪怕只是放1个,就会发现CPU2上面的定时器中断开始增加:

癓inux高性能任务独占CPU举例分析"

这说明一点,哪怕隔离的CPU上面只有一个线程去跑,计时器蜱虫就会开始跑,当然,这个计时器,蜱虫也会频繁打断这一个线程,从而造成大量的上下文切换。你肯定会觉得Linux怎么这么傻,既然只有一个人,那也没有时间片分片的必要的,不需要在2个或者多个任务进行时间片划分地调度,为啥还要跑蜱虫?其实原因是我们的内核默认只是使能了闲置的NO_HZ:

Linux高性能任务独占CPU举例分析