Linux内核之进程4:CPU的负载均衡
1.线程的负载均衡
对task_struct做负载均衡;
分布式系统中,linux的每个核都自动以劳动为乐,(共产主义社会)。
分别对RT任务和普通线程做负载均衡:
RT任务:将n个优先级最高的线程自动分配到n个核;
pull_rt_task()
push_rt_task()
普通任务:
周期性负载均衡,在时钟tick会检查哪个核空闲,优先使空闲核工作(从负载重的核pull任务,或push任务给空闲核,每个CPU以劳动为乐);
idle时负载均衡;某个核进入idle状态,会主动pull任务执行;
fork和exec时负载均衡;创建的新进程,会放到最闲的核去跑;
软亲和性(affinity) Linux 内核进程调度器天生就具有被称为软 CPU
亲和性(affinity)的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。
硬亲和性(affinity): 就是利用linux内核提供给用户的API,强行将进程或者线程绑定到某一个指定的cpu核运行。
需要绑定CPU的原因:
1.提高cache命中率;
2.在一些非对称CPU,比如NUMA中,防止一个CPU去另外一个插槽的内存读写数据;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3FL0WWc-1598434477156)(media/52aa1f9fd24453f17c439a87af15793a.png)]](https://i-blog.csdnimg.cn/blog_migrate/274cd64ee722931aef1d5c613c06494e.png#pic_center)
也可以用taskset工具设置:-a 所有线程
pidof ./a.out
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eN7CnHBC-1598434477159)(media/b4a4e74dc6c46517c87d58153608a17d.png)]](https://i-blog.csdnimg.cn/blog_migrate/8fc87440b70d9640da12fedf88d0798e.png#pic_center)
进程a.out占用CPU800%(八核)

设置只在2号核跑
taskset -a -p 02 554
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NidR298g-1598434477162)(media/b1e199c95c9d8761ac4fcb1210dd3530.png)]](https://i-blog.csdnimg.cn/blog_migrate/5caa7a2134b1da75d5b991b958d53f0a.png#pic_center)
CPU占有率降至100%,所有线程只在2号核上跑;
2.中断负载均衡
负载除了进程还有中断,执行完中断,才会去执行task_struct任务;
硬件中断一般比较短(linux2.6.34后内核不支持中断嵌套),比如网卡收包,在硬中断接收完包,会调用软中断(处理tcp/ip包,软中断可以嵌套),软中断结束后,会调用vtime最小的线程;
top命令的hi表示硬中断时间(isr,屏蔽中断),si表示软中断,
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Amk0xvTq-1598434477164)(media/8676f373467191ec33103b88b4c06edb.png)]](https://i-blog.csdnimg.cn/blog_migrate/141ed77f84015bf53b829f2dfa722196.png#pic_center)
当网络流量大的时候,CPU花在硬中断和软中断时间比较多,这时候需要做中断的负载均衡;
现在新网卡一般有多个队列,假如在一个4核的系统,网卡有4个队列,每个队列可以单独产生中断,硬件支持负载均衡;那么可以将一个队列绑定到一个核,这样,所有CPU都会参与网卡发送包服务;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nvjbijdT-1598434477165)(media/96da26784727858d0555123c96622cc9.png)]](https://i-blog.csdnimg.cn/blog_migrate/b550ebbde53446db87c142f16588dd96.png#pic_center)
设定方法:将每个中断号,分别设置affinity,绑定到指定CPU
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hzs8dbVH-1598434477167)(media/dff1b11c1711d8108196f1298f6906d0.png)]](https://i-blog.csdnimg.cn/blog_migrate/19d88ccde3aae44cc70d87c075dd8b3d.png#pic_center)
cat /proc/interrupts |grep ‘enp’
124: 0 0 0 0 0 0 0 34 415207449 PCI-MSI 1572864-edge enp3s0
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vw8pb6le-1598434477168)(media/420f618cee58dc40f482e0cbe7006d2f.png)]](https://i-blog.csdnimg.cn/blog_migrate/6f98f9e16c8f85cbfa6311c9db7b3ffe.png#pic_center)
sudo sh -c “echo 3 > /proc/irq/124/smp_affinity”
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AIGoy9Nx-1598434477169)(media/67b4cbc315f0f874e7af4a0d605a813a.png)]](https://i-blog.csdnimg.cn/blog_migrate/ba0cfe486abd577288ef6ab52fa53cf0.png#pic_center)
有的网卡只有一个队列:单个核抛出的软中断只能在这个核跑,那么一个队列抛出的软中断(tcp/ip层处理)只能在这一个核执行,其他核会空闲;
测试:
客户端:$ echo “不要回答!不要回答!不要回答!” | nc 10.10.100.16 1235
服务端:$ nc -l -p 1235
3 RPS补丁
Google推出了rps补丁,可以把TCP/IP协议栈的处理,均衡到多个核上去,这个技术叫RPS;
比如我手头板子是单个网卡队列收包,默认是单核上执行
#cat /sys/class/net/eth0/queues/rx-0/rps_cpus
0
收包只在CPU0上执行
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qXBmmozG-1598434477170)(media/0026c188b5f6ca6e5b63354058586b27.jpg)]](https://i-blog.csdnimg.cn/blog_migrate/34fc5210e98fcdcdfaadc7cab803458e.png#pic_center)
nc -l -p 1235
监听1235端口收到数据时,只有CPU0继续增加;
多核间的softIRQ scaling
设置rps在CPU0/1上均衡
echo 3 > /sys/class/net/eth0/queues/rx-0/rps_cpus
watch –d “cat /proc/softirqs | grep NET_RX”
/proc/interrupt
/proc/softirq
分别查看硬中断和软中断次数
top +1显示多核的负载
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YaWYi0LV-1598434477170)(media/c17214473f4b2c4d9e9406d25f4bba9a.jpg)]](https://i-blog.csdnimg.cn/blog_migrate/05077d029027e4379e2a8bbd5ef7ec1b.png#pic_center)
由上可以看到CPU0/1都开始处理网络接收包
经实验得出结论:
- 硬中断绑定的CPU核,一定会响应softirqs,不管对应rps_cpus位设置与否;
2.当rps_cpus位设置时,对应CPU核会响应softirqs;
RPS原理:由单一CPU核响应硬件中断,将大量网络接收包,通过多核间中断方式分发给其他空闲核,如下网络图清晰说明情况
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A1iV8sIa-1598434477171)(media/8605b2ff372d6a32e0ed714ea9005a54.jpg)]](https://i-blog.csdnimg.cn/blog_migrate/76310383dde8ad4fba40c41ea5d5678e.png#pic_center)
上图引用自https://blog.csdn.net/dog250/article/details/46705657
4.linux不是硬实时系统:
硬实时:满足可预期,非一定越快越好,强调的是截止期限的可预期性;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KbZbHb2V-1598434477172)(media/15915128959344eb2f476a0074a59997.png)]](https://i-blog.csdnimg.cn/blog_migrate/c47e29b3729ca6b0826f47aeffe2b205.png#pic_center)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nOFzVK0M-1598434477172)(media/177819b33a9db50544ecfca74cb7bc26.png)]](https://i-blog.csdnimg.cn/blog_migrate/7bba4502ee0a72ae7de4b3a7e0ac71c6.png#pic_center)
Linux的设计决定了她不是硬实时系统,有些情况(比如spin_lock)不可抢占,其不可预期,是软实时系统;
用什么系统由场景决定,并非硬实时一定优于软实时。
Linux的抢占算法演变,越新的内核支持抢占越多;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6F1uEAkM-1598434477173)(media/335b8d378fe8e572d936e331de95125a.png)]](https://i-blog.csdnimg.cn/blog_migrate/b7ccf7ebf3e084df8c35a9d00111d30c.png#pic_center)
Linux的CPU消耗主要分以下几种:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wLYdujqN-1598434477174)(media/4b24fec5cb71daf4fe1ec5f22fdb957c.png)]](https://i-blog.csdnimg.cn/blog_migrate/c9deb5035544320111f54ac7a3a1dfd0.png#pic_center)
内核态的spin_lock,是自旋锁,用户态不是;
1,2,3都不可抢占,所以linux不是一个硬实时系统,硬实时系统要求任何时刻都可以抢占。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qIORGrpo-1598434477175)(media/e36e3bb4aeb89684a92d0a0506c6e74b.png)]](https://i-blog.csdnimg.cn/blog_migrate/bdcfa86476da6a310962e140ad9541dc.png#pic_center)
T3时刻唤醒一个更高优先级RT线程,
RT线程只能到T5时刻(硬中断,软中断都执行完,并且释放spin_lock之后)才能抢占,等待时间是未知的。
要解决linux硬实时性,需要打rt补丁,
补丁不在mainline中,维护网站;
https://wiki.linuxfoundation.org/realtime/start
https://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git/
rt补丁
将所有中断线程化,
去掉软中断,
spin_lock改成mutex实现,即系统中只有上图第4类进程,任何线程都可以被抢占;
使延迟变为可预期,即成为硬实时系统。
不是每一个内核版本都有相应rt补丁。
rt可以将linux延迟做到100us量级(1G CPU),同时吞吐会下降。
打上补丁后如下图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9WeLt5WL-1598434477175)(media/8a81a05de77d1106d9d304200e6ed7e4.png)]](https://i-blog.csdnimg.cn/blog_migrate/807702ec6a3ad2e272e902119b40f0de.png#pic_center)
Server:不抢占
Desktop: kernel不抢占
Low-Latency Destktop:手机用,kernel也抢占
Real-Time:完全抢占;
调度器实时后,linux还不一定实时,有无数内存坑,比如内存管理部分,ROW,写内存时发现内存尚未分配,此时无法保持实时性。
其他方法:
同时运行两个系统,实时任务放在RTOS跑,非实时任务放在Linux跑。
比如单反,一般用两个系统,传统拍照用实时系统,涉及网络相关任务放在linux,利用linux强大的网络协议栈。
5.Deadline调度算法
https://elinux.org/images/f/fe/Using_SCHED_DEADLINE.pdf
如下场景需求,系统有两个任务,核电站任务要求运行1/2s, 洗衣机要求运行20ms/200ms;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QbtYYMD8-1598434477176)(media/3348d1c02a47687260783f927096db9f.png)]](https://i-blog.csdnimg.cn/blog_migrate/98ff80d7e5c0fd36bff9daafe70956c5.png#pic_center)
用传统RT或CFS调度算法,必须设置洗衣机优先级更高才能满足需求。(核电站优先级更高将独占CPU超过0.5s,
下一个周期无法满足CPU需求)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsUZfTS0-1598434477177)(media/57adde06823a584d8e81b01f51305901.png)]](https://i-blog.csdnimg.cn/blog_migrate/67ed89905855f2f93d7fe7269c318097.png#pic_center)
但当系统有多个任务,比如核电站要求800ms周期内必须跑500ms,洗碗机要求300/900ms,
洗衣机要求100/800ms:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m2fq0PZD-1598434477177)(media/0b4ca210392d6ac1879eec32f7277bd9.png)]](https://i-blog.csdnimg.cn/blog_migrate/49d6d3c808cccb9cd043c93635d3ce68.png#pic_center)
总的CPU消耗是小于100%的。但是按照传统RR算法,无法满足调度需求;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZkAlqNId-1598434477178)(media/7deda790debaa20accc7daf27536c85c.png)]](https://i-blog.csdnimg.cn/blog_migrate/dd27fecc4c18e98aa06982151a982bfb.png#pic_center)
Linux提供了一个Rate Monotonic Scheduling:
Deadline调度算法思想:当产生一个调度点的时候,DL调度器总是选择其Deadline距离当前时间点最近的那个任务并调度它执行,谁更紧急,谁先跑;
Deadline需要设置三个参数,周期Period,Deadline, Runtime
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rp3aSvqj-1598434477179)(media/1876c8bcd26856e1bfc8ff3c0852caf1.png)]](https://i-blog.csdnimg.cn/blog_migrate/43c5edcb9704c33888fe3f528e05b30b.png#pic_center)
deadline调度器虽然可以保证每个RT任务在deadline之前完成,但是并不能保证每一个任务的最小响应时间。
内核实例,sched-deadline.c
设置允许普通用户修改app调度策略
sudo setcap 'cap_sys_nice=eip' ./a.out
pidof ./a.out
sudo chrt -d -T 1000000 -P 3000000 -D 2000000 0 pid
sudo chrt -p pid
$ sudo chrt -p 6276
chrt: unknown scheduling policy
pid 6276's current scheduling policy: pid 6276's current scheduling priority: 0
chrt 版本太低,未支持显示deadline参数;
Deadline在top显示rt进程,
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)