【Linux进程、线程、任务调度】四多核下负载均衡 中断负载均衡,RPS软中断负载均衡 cgroups与CPU资源分群分配 Linux为什么不是硬实时 preempt-rt对Linux实时性的改造

学习交流加

  • 个人qq:
    1126137994
  • 个人微信:
    liu1126137994
  • 学习交流资源分享qq群:
    962535112

上一篇文章(点击链接:点击链接阅读上一篇文章)讲了:

  • CPU/IO消耗型进程
  • 吞吐率 vs. 响应
  • SCHED_FIFO算法 与 SCHED_RR算法
  • SCHED_NORMAL算法 和 CFS算法
  • nice与renice
  • chrt

本篇文章接着上一篇文章讲解以下内容:

  • 多核下负载均衡
  • 中断负载均衡,RPS软中断负载均衡
  • cgroups与CPU资源分群分配
  • Linux为什么不是硬实时
  • preempt-rt对Linux实时性的改造

文章目录

    • 1、多核下负载均衡
    • 2、CPU task affinity
    • 3、IRQ affinity
    • 4、进程间的分群(cgroup)
    • 5、 Hard realtime - 可预期性
    • 6、PREEMPT_RT补丁
    • 7、总结

1、多核下负载均衡

我们知道现在的CPU都是多核的。我们可以认为在同一时刻,同一个核中只能有一个进程(task_struct,调度单位但是task_struct)在运行。但是多核的时候,在同一个时刻,不同的核中的进程是可以同时运行的。

假设你电脑有四个核,现在每个核都在跑一个线程。各个核上都是独立的使用SCHED_FIFO算法、SCHED_RR算法与CFS完全公平调度算法去调度自己核上的task_struct,但是为了能够使整个系统的负载能够达到均衡(各个核的调度情况尽量保持一致,不要使某一个核太忙也不能使某一个核太轻松),某一个核也有可能会把自己的task_struct给另一个核,让另一个核来调度它。各个核都是以劳动为乐,会接收更多的任务,核与核之间进行pull与push操作将各自的task_struct给其他核或者拿其他核的task_struct来调度。这样的话,整个系统就会达到一种负载均衡的效果。我们称之为多核下的负载均衡。

那么不同的进程如何做到负载均衡呢?

  • RT进程

N个优先级最高的进程分不到N个不同的核,使用pull_rt_task与push_rt_task来达到负载均衡的效果。RT进程的话,实际上强调的是实时性而不是负载均衡。

  • 普通进程

分为:

  1. 周期性负载均衡(普通进程不会抢占,就所有的进程周期性的被各个核调度达到多个CPU的负载均衡)
  2. IDLE时负载均衡(某一个核假设为CPU1是空闲的,0号进程想要过来让CPU1跑,CPU1才不会去跑0号进程,CPU1会去看其他核是否在忙,如果其他核在忙,CPU1就会拿其他核的任务过来跑,CPU是尽量不会去跑0号进程的,因为一旦跑了0号进程,说明整个系统处于一种低功耗的状态,这种状态下整个系统只有0号进程会跑,其他进程都在休眠)
  3. fork和exec时负载均衡(fork会创建一个新的task_struct,而exec只是替换进程虚拟地址空间的.data与.text,当创建一个新的进程或者替换了一个新进程,就会把这个新的task_struct推给一个最空闲的核去调度。)
  • 实验

two-loops.c

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>void *thread_fun(void *param)
{printf("thread pid:%d, tid:%lu\n", getpid(), pthread_self());while (1) ;return NULL;
}int main(void)
{pthread_t tid1, tid2;int ret;printf("main pid:%d, tid:%lu\n", getpid(), pthread_self());ret = pthread_create(&tid1, NULL, thread_fun, NULL);if (ret == -1) {perror("cannot create new thread");return 1;}ret = pthread_create(&tid2, NULL, thread_fun, NULL);if (ret == -1) {perror("cannot create new thread");return 1;}if (pthread_join(tid1, NULL) != 0) {perror("call pthread_join function fail");return 1;}if (pthread_join(tid2, NULL) != 0) {perror("call pthread_join function fail");return 1;}return 0;
}

编译运行:

$ gcc two-loops.c -pthread
$ time ./a.out

在这里插入图片描述

  • 结果分析

由于我的虚拟机中Linux是两个核的,在两个核中分别跑的时间加起来,大概等于我们用户态的时间。这说明两个线程被分配到两个核中分别跑的。

2、CPU task affinity

affinity的意思是亲和,实际上我们这里是指,让task_struct对某一个或若干个CPU亲和。也就是让task_struct只在某几个核上跑,不去其他核上跑。这样实际上破坏了多核的负载均衡。

如何实现CPU task affinity?

  1. 可以在程序中直接写代码设置掩码
int pthread_attr_setaffinity_np(pthread_attr_t *, size_t, const cpu_set_t *);
int pthread_attr_getaffinity_np(pthread_attr_t *, size_t, cpu_set_t *);
int sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);
int sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);

设置掩码来保证某一个线程对某几个核亲和,比如下方的0x6(110),就是设置线程只能在核2与核1上运行

  1. taskset工具

比如:

$ taskset -a -p 01 19999

-a:进程中的所有线程,01掩码,19999进程pid

  • 实验

编译上述two-loops.c, gcc two-loops.c -pthread,运行一份

$ ./a.out &

top查看CPU占用率:
在这里插入图片描述

把它的所有线程affinity设置为01, 02, 03后分辨来看看CPU利用率

$  taskset -a -p 02 进程PID
$  taskset -a -p 01 进程PID
$  taskset -a -p 03 进程PID
  • 前两次设置后,a.out CPU利用率应该接近100%,最后一次接近200%

3、IRQ affinity

中断也可以达到负载均衡。

假设有四个网卡,当网卡收到数据,会触发中断,将四个网卡队列的中断均分给四个CPU

  • my ethernet
    /proc/irq/74/smp_affinity 000001
    /proc/irq/75/smp_affinity 000002
    /proc/irq/76/smp_affinity 000004
    /proc/irq/77/smp_affinity 000008

在这里插入图片描述
以上四个网卡的中断全部均分给了四个CPU。

当然中断也可以像进程一样让其affinity某个进程,比如向下面这样,可以让01号中断分配给某个CPU,让其affinity该CPU。

分配IRQ到某个CPU

[root@boss ~]# echo 01 > /proc/irq/145/smp_affinity
[root@boss ~]# cat /proc/irq/145/smp_affinity
00000001

有一种情况比较特殊:假设一个CPU0上有一个中断IRQ,该中断处理函数中可能会调用软中断(soft_irq)处理函数。那么这个软中断处理函数又会占用该CPU0。那么该CPU0就会处于非常忙的状态,达不到负载均衡。如何使软中断去其他核执行?
在这里插入图片描述

使用RPS解决多核间的softIRQ scaling 。

RPS可以将包处理(中断里面的处理,其实就是软中断)负载均衡到多个CPU

例如:

[root@machine1 ~]# echo fffe > /sys/class/net/eth1/queues/rx-0/rps_cpus
将中断分配给0~15的核,这样可以使所有核共同处理中断以及中断内部的软中断,处理TCP/IP包的解析过程

4、进程间的分群(cgroup)

进程间的分群:假设有一个编译Android系统的服务器,两个人A与B同时要使用该服务器编译程序,A编译程序创建了1000个线程,B编译程序创建了32个线程,那么如果按正常的CFS调度的话,A的程序会获得1000/1032的CPU时间,B的程序会获得32/1032的CPU时间,这样的话就会导致编译B可能会花与A相同的时间才能将程序编译完,这样就显得很对B不公平(想想我B本身可能是一个小程序,却要编译半天,多难受啊)。Linux为了解决类似的这种问题,采用了进程间的分群思想:让A的线程放在一个群中,B的线程放在一个群中,给A群与B群采用CFS调度各个群,然后再在A群与B群内部采用CFS调度群内的进程。这样的话,就显得公平一些。不会说编译一个小程序花费太多时间。
在这里插入图片描述

实际上分群使用的是树结构,上图可以清晰的理解。

  • 实验

编译two-loops.c, gcc two-loops.c -pthread,运行三份

$ ./a.out &
$ ./a.out &
$ ./a.out &

用top观察CPU利用率,大概各自66%。
在这里插入图片描述

  • 创建A,B两个cgroup

    /sys/fs/cgroup/cpu$ sudo mkdir A
    /sys/fs/cgroup/cpu$ sudo mkdir B

  • 把3个a.out中的2个加到A,1个加到B。

    /sys/fs/cgroup/cpu/A$ sudo sh -c ‘echo 3407 > cgroup.procs’
    /sys/fs/cgroup/cpu/A$ sudo sh -c ‘echo 3413 > cgroup.procs’
    /sys/fs/cgroup/cpu/A$ cd …
    /sys/fs/cgroup/cpu$ cd B/
    /sys/fs/cgroup/cpu/B$ sudo sh -c ‘echo 3410 > cgroup.procs’

  • 这次发现3个a.out的CPU利用率大概是50%, 50%, 100%。

5、 Hard realtime - 可预期性

硬实时:可预期性。当一个线程被唤醒,直到这个线程被调度的这个时间段,不超过某一个预定的截止期限。称为硬实时。如果该线程被唤醒后,被调度的时间允许超过那个截止期限,那么就不是硬实时。Linux系统不是硬实时。
在这里插入图片描述

以上图我们可以看到。Linux系统并不是硬实时系统,也就是说对于一个进程,什么时间之前(注意我们不能说在什么时候能够被调度到,因为我们无法确定一个进程什么时候能够被调度到)能够被调度到,我们并不知道。那么Linux为什么不是硬实时?

首先我们需要理解Linux系统中,有四类区间:

在这里插入图片描述
当Linux跑起来后,CPU的时间都花在上述四类区间上。

  • 中断状态:

当系统中有中断,CPU不能再调度任何其他进程,就算RT进程来了也一样得等着中断结束后的一瞬间才能抢占CPU。而且,在中断中,不能再进行中断,也就是说,中断必须结束才能干其他事。中断是必须要被处理的。

  • 软中断

软中断中可以被中断。但是软中断中如果唤醒一个RT进程,此RT进程也不会被调度。

  • 进程处于spin_lock(自旋锁)

自旋锁是发生在两个核之间的。当某一个核如CPU0上的进程获取spin_lock后,该核的调度器将被关闭。如果另一个核如CPU1的进程task_struct1此时想要获取spin_lock,那么task_struct1将自旋。自旋的意思就是不停的来查看是否spin_lock被解锁,不停的占用CPU直到可以获取spin_lock为止。

所以进程如果处于spin_lock,那么其他任何进程不会被调度。

  • 进程处于THREAD_RUNNING态

当进程处于THREAD_RUNNING态,它就是可调度的,只有在这种状态下,CPU才支持抢占。也就是说在这种状态,加入CPU正在运行一个普通进程,此时如果某一个RT进程被唤醒,那么该RT进程就会去抢占CPU。

上述四类区间:如果可抢占的RT进程被唤醒在前三类区间,那么该RT进程,必须等待这三类区间的事件完成结束的一瞬间抢占,否则RT进程也不会被CPU调度。如果在第四类区间上唤醒一个RT进程,则该RT进程立即抢占CPU。

理解了以上四类区间,就很容易理解Linux为什么不是硬实时了,看下图:
在这里插入图片描述

分析:

上图横轴为时间轴。T0,T1,T2…为某一时刻。

  • 系统运行分析:

T0时刻,假设有一个系统调用陷入到内核中。此时在跑的是一个普通进程(Normal task),在T1时刻,该Normal task获取了一个spin_lock。
到了T2时刻,突然来了一个中断IRQ1,则系统执行中断处理函数IRQ1 handle人(),再中断处理函数中又调用软中断(Soft IRQ),在软中断中的T3时刻,唤醒了一个RT进程。此时由于系统处于软中断状态,所以RT进程无法抢占CPU(红色虚线部分为无法抢占CPU)。在T4(软中断执行期间)时刻,又来了一个中断IRQ2(说明软中断中可以中断),然后系统执行中断处理函数IRQ2 handler(),然后执行软中断处理函数。到T5时刻中断与软中断执行完毕。但是由于此时Normal task还处于spin_lock状态,所以之前被唤醒的RT进程还是依然无法占用CPU。直到T6时刻,Normal task释放了spin_lock的一瞬间,RT进程抢占了CPU。当RT进程执行完,才会把CPU还给最开始还没有执行完的Normal task。Normal task执行完后,退出内核的系统调用。

  • 结果分析:

从以上分析可以看出,从T3时刻RT进程被唤醒,到T6时刻,RT进程开始执行,这段时间,我们是无法预测的,我们无法给出一个有限的上限值来度量T6-T3的值。因为在这期间,有可能会来各种中断,有可能进程会一直处于spin_lock状态不放。所以,我们无法确定T6-T3的时间段。所以根据硬实时的概念知,Linux系统,不是硬实时。

6、PREEMPT_RT补丁

可以对Linux系统打实时补丁来增加Linux 的实时性。

比如PREEMPT_RT补丁,主要的原理如下:

  • spinlock迁移为可调度的mutex,同时报了raw_spinlock_t
  • 实现优先级继承协议
  • 中断线程化
  • 软中断线程化

将spin_lock与中断,软中断,都改造成第四类区间的可调度区间,就可以实现Linux系统的硬实时性。比如当中断线程化,当产生中断时,不执行中断处理程序,直接返回。只有很小的区间是不可抢占的。

  • 以上四种方法原理,后期会详细研究,这里不再赘述。

7、总结

本文主要掌握:

  • 多核下负载均衡
  • 中断负载均衡,RPS软中断负载均衡
  • cgroups与CPU资源分群分配
  • Linux为什么不是硬实时
  • preempt-rt对Linux实时性的改造

探讨学习加:
qq:1126137994
微信:liu1126137994

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/422737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

主机关机后第二天就无法开机_iphone没电自动关机后无法充电和开机的解决办法!(亲身经历)...

问题记录时间: 2020年5月21日地点: 北京市朝阳区XXX写字楼​ 今天下午工作太忙,突然发现我的iphone8(ios13)还剩下1%的电量,赶紧去找充电器,没找到!抓紧借!回来的时候为时已晚,我的小8已经电量耗尽关机了.插上源电尝试开机,我心里想着千万不要出问题,结果还是怕什么来什么,手机…

推荐学习-Linux性能优化实战

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a;个人微信&#xff1a; liu1126137994学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff1a; 780902027 推荐一个学习资源&#xff1a;Linux性能优…

创业冲突的五种解决方法是_失眠原因不同,中医五种调理方法解决问题!

请点击上面 免费关注...中国健康养生堂&#xff0c;关注国人健康&#xff0c;每天与你分享健康资讯、保健常识、心理健康、中医养生、健康饮食、养生食疗、健康知识、生活常识、两性健康&#xff0c;远离亚健康&#xff0c;健康是一种心态&#xff01;懂点健康养生&#xff0c;…

C++从入门到进阶近100本书推荐电子书pdf

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a; 个人微信&#xff1a; liu1126137994 学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112 学习交流资源分享qq群2&#xff08;已满&#xff09;&#xff1a; 780902027 学习…

HTML5学习笔记

HTML5可以做的事情 1. 制作时尚的表单 2. 构建实用的HTML5框架 3. 开发丰富多彩的游戏 4. 以更直观的方式让数据可视化呈现 5. HTML5的未来 – 惊艳的HTML5示例和实验 HTML的新特点 新特性 HTML5 中的一些有趣的新特性&#xff1a; 用于绘画的 canvas 元素 用于媒介回放的 v…

特别慢_这款“爱豆”很特别,它带你重温旧时光,体验慢生活的时代

说到浪漫之都的法国巴黎&#xff0c;就不得不让人想到卢浮宫、凡尔赛宫、凯旋门等古老建筑&#xff0c;当然还有让全世界震惊的埃菲尔铁塔&#xff0c;这些名胜古迹无一不让法国人民感到骄傲。如果问及法国巴黎有着华人家乡味道的&#xff0c;就不得不说到一间不起眼的老式港式…

MarkDown编辑器中数学公式与符号-LaTeX 各种数学命令,符号

函数、符号及特殊字符 声调 语法效果语法效果语法效果\bar{x}\acute{\eta}\check{\alpha}\grave{\eta}\breve{a}\ddot{y}\dot{x}\hat{\alpha}\tilde{\iota}函数 语法效果语法效果语法效果\sin\theta\cos\theta\tan\theta\arcsin\frac{L}{r}\arccos\frac{T}{r}\arctan\frac{L}{T…

spark中dataframe解析_Spark-SQL

fe缺点不方便添加新的优化策略线程安全问题Spark SQL支持三种语言javaScalapythonDataFrame大规模数据化结构能历、提高了运算能力从sql到dataFrame的转化&#xff0c;支持sql查询RDD是分布式的java对象的集合&#xff0c;对象颞部结构不可知dataframe以rdd为基础的分布式数据集…

【算法设计与分析】01 算法涉及的研究内容概述

文章目录1 算法的研究内容2 算法设计的两个例子2.1 调度问题2.2 算法设计的步骤2.3 投资问题3 总结在学习算法涉及与分析的内容之前&#xff0c;先了解一下算法所涉及的几个大块的内容&#xff0c;方便以后学习。1 算法的研究内容 算法的研究内容主要包括三点&#xff1a; 计…

CSDN博客图片水印|自定义水印|去除水印

参考博文1&#xff1a;https://blog.csdn.net/stereohomology/article/details/54561782 参考博文2&#xff1a;https://blog.csdn.net/u011479200/article/details/81026798 CSDN改版后&#xff0c;原来的修改方法不行了~~ 在 CSDN 中&#xff0c;上传图片时&#xff0c;会默…

【算法设计与分析】02 货郎问题与计算复杂性理论

什么是NP系列问题&#xff1f;今天来看看这些问题。 文章目录1 货郎问题2 0-1背包问题3 什么是NP-hard问题&#xff08;NP难问题&#xff09;1 货郎问题 问题&#xff1a;有n个城市&#xff0c;已知任何两个城市之间的距离&#xff0c;求一条每个城市恰好经过1次的回路&#xf…

ad17编辑界面怎么检查未连线_软件账务处理流程之——凭证审核与检查

金蝶是我们财务人非常熟悉的财务软件&#xff0c;但是我们很多财务人只在应用软件的时候还是会出现很多的问题&#xff0c;为了帮助大家更好地应用这个软件&#xff0c;今天就来和大家讲讲关于金蝶软件凭证审核与检查的一些基本处理流程。凭证审核凭证输入完成后&#xff0c;更…

快速可扩展的Ajax流代理——提供持续下载跨域数据

简介 由于浏览器禁止跨域的XMLHTTP调用&#xff0c;所有的Ajax网站都必须有一个服务端代理来从外部域比如Flickr或者Digg来抓去内容。对客户端Javascript代码来说&#xff0c;一个XMLHttp的调用将请求传递给宿主在相同域里的服务端代理&#xff0c;然后由代理来从外部服务器上下…

Markdown编辑器 公式指导手册

#Cmd Markdown 公式指导手册 标签&#xff1a; Tutorial 2018-03-20 补档&#xff1a; 收到很多小伙伴对本文的源文档转载需求&#xff0c;故传了一份 md 文件&#xff0c;请按需 下载 。 本文固定链接: https://www.zybuluo.com/codeep/note/163962 点击跳转至 Cmd Markdown …

【算法设计与分析】03 算法及其时间复杂度

在学习算法的时间复杂度之前&#xff0c;需要了解下面5条概念 什么是算法的时间复杂度&#xff1f; 针对指定基本运算&#xff0c;计数算法所做的运算次数。什么是基本运算&#xff1f;比较、加法、乘法、置指针、交换…什么是输入规模&#xff1f;输入串的编码长度&#xff0c…

用单片机测量流体流速的_影响超声波流量计(热量表)测量精度的主要因素

1、上下游直管段的影响由于时差式超声波流量计标定系数K值是雷诺数函数&#xff0c;所以当流体从层流过渡到紊流时&#xff0c;其流速分布不均匀&#xff0c;标定系数K值将产生较大的变化&#xff0c;从而影响测量准确度。根据设计要求换能器应安装在上游直管段为10倍管径、下游…

c语言头文件和源文件_C语言头文件防卫式声明

C语言一般提供三种预处理功能&#xff1a;宏处理、文件包含、条件编译。头文件防卫式申明中会用到条件编译中 #ifndef、#define、#endif 的用法。所以&#xff0c;首先价绍下条件编译。1 条件编译一般情况下&#xff0c;在生成可执行文件的过程中&#xff0c;源程序文件中的所有…

Firebug控制台详解

作者&#xff1a; 阮一峰 日期&#xff1a; 2011年3月26日 Firebug是网页开发的利器&#xff0c;能够极大地提升工作效率。 但是&#xff0c;它不太容易上手。我曾经翻译过一篇《Firebug入门指南》&#xff0c;介绍了一些基本用法。今天&#xff0c;继续介绍它的高级用法。 Fi…

标签 href 怎么拼接_【微信】用户-标签的兴趣建模

这一篇分享的是CIKM2020微信的learning to build user-tag profile&#xff0c;主要介绍了微信看一看&#xff08;"Top Stories"&#xff09;中&#xff0c;如何进行用户-标签的兴趣建模&#xff0c;提升推荐效果。1、背景看一下微信看一看场景下的推荐流程&#xff…