Linux内核之进程3:进程调度

1. 吞吐率和响应

吞吐:单位时间内做的有用功;

响应:低延迟。

吞吐追求的整个系统CPU做有用功,响应追求的是某个特定任务的延迟低;

1GHZ的CPU切换线程保存恢复现场约几个微妙级别,看似消耗不了太多时间,但是由于系统的局部性原理,会保存当前线程数据的缓存,切换线程会打乱局部性引起cache miss,而CPU访问cache速度远大于内存访问,这样综合看来上下文切换花销还是很大的。无用功占用较多CPU;

追求吞吐量和低延迟,这两个目标是矛盾的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KhDnlhZs-1598434032345)(media/c4d9c2c1686d8df15bc1af76c899f94c.png)]

编译内核选项有如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xrz8xO6e-1598434032348)(media/027c577abd52b52215a88606fefe5581.png)]

服务器版追求吞吐量,配置为不抢占;桌面版或手机更追求响应,配置为低延迟;

调度器一般讲的是最后一种,低延迟抢占;

2. Linux任务类型

问题2: 一个典型的系统内任务分两种:CPU消耗型和IO消耗型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yPgQVGLb-1598434032350)(media/61b09038e75c3d3e2baced98bf2a5cd2.png)]

CPU型的任务,通常要求高性能,但是不追求低延迟,优先级较低;

IO型的任务,通常优先级更高,追求低延迟,对CPU性能不敏感;

如下图,一个读IO循环过程,占用CPU时间极短(1ms),IO占用100ms
,若CPU性能降一倍,执行CPU占用2ms对整体时间影响不大(总时间102ms);但是如果CPU不能及时响应,一个读写周期响应延迟100ms,那整体时间变为约200ms,整体性能降低一半;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrjqaaSX-1598434032353)(media/16fbbd27542e6d7f3dcb745df711c6eb.png)]

所以,IO型任务只关注响应速度,对CPU性能不敏感;

基于此原理ARM公司设计了big.LITTLE架构,比如在手机上有8个核,设计为四大核,四小核;大小核指令集完全兼容,调度器调配IO型的任务跑在小核上(对CPU弱不敏感),CPU型任务放在大核上跑。这样用4+1(四小核等效)核的功耗实现了8核的性能;

调度器要在吞吐和延迟之间找到某个均衡;

3 任务调度

1调度原理:

涉及两个概念,策略优先级

内核所有进程优先级为0~139之间;

0~99:采用RT策略,常用的有SCHED_FIFO, SCHED_RR;

SCHED_FIFO, 属于霸占型的,高优先级执行完,才会执行低优先级;

SCHED_RR, 不同优先级与CHED_FIFO相同,属于霸占型,同等优先级轮转;

比如有4个进程:P1_FIFO_3, P2_CHED_RR_2, P3_CHED_RR_2, P4_FIFO_4

执行过程,P2/P3轮转执行完之后,执行P1, 最后执行P4。

100~139:普通线程,采用非RT策略,对应nice(-20, 19).

这里所有优先级都是可以抢占的,但nice 值越低,分配CPU资源越多。

2.所有调度,SCHER_FIFO/SCHER_RR或设置nice都是针对task_struct;

3.将进程设置为FIFO策略:

修改进程25020的策略为FIFO, 优先级50

sudo chrt –f –a –p 50 25020

这样进程是按FIFO策略调度,占有CPU最高为80%(普通进程可以接近100%),CPU占有率降低(但不可抢占),此时IO延迟反而变大,鼠标操作变慢;

设置FIFO线程api

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f4DSmlN5-1598434032354)(media/1615dfdee1ef3f51e9c63445067f02b3.png)]

内核里优先级=99-50=49

内核态数字越低,优先级越高;用户态相反;

4.每个task_struct的nice都可以单独设置(所有普通线程);

Nice值设置都是指普通线程,RT策略不支持nice;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-92kMjbnu-1598434032356)(media/19aff69f52cbba2224832f52f024a21d.png)]

nice()默认是0

调度,在不同nice值进程间轮转,

2.6早期内核对进程采取奖励和惩罚算法,越睡眠越奖励,越消耗CPU,越惩罚,动态调整nice值,实现极其复杂,后来升级两个补丁;

补丁1:RT熔断机制,设置rt门限值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mPsKsU0m-1598434032356)(media/0d93fb4698ac0c63e796d7979f525945.png)]

默认runtime 0.95s,period 1s,1s内RT最多跑了0.95s自动熔断;

$cd /proc/sys/kernel

sudo sh -c ‘echo 800000 > sched_rt_runtime_us’

设置RR/FIFO策略熔断最高位800ms,RR/FIFO策略进程最多占用CPU 80%。(默认是95%)

补丁2:普通进程调度算法CFS(complete fare schedule)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K0fgT8uP-1598434032357)(media/4fec6beb049bdfbb7fa496ea7dd31c8f.png)]

虚拟运行时间,vtime = ptime * 1024/weight

ptime:物理时间

weight:权重参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ioy1bvcO-1598434032358)(media/65574db8b2370ab2085579ce97d6f945.png)]

nice=0,虚拟时间等于物理时间;

nice值越小,对应weight分母越大,vtime增长越慢,实际对应ptime占用越多;

vtime机制很好的平衡了I/O型,CPU型任务;

I/O型喜欢睡眠,ptime比较小,所以vtime自然较小,会偏向于挂在树左边;

同理,优先级越高的CPU型,其weight值越大,vtime也会越小,亦偏向挂载树左边;

即CFS用很简单的方式实现了历史上复杂的睡眠补偿,消耗惩罚,动态调整等功能;

修改进程的nice值:

sudo renice -n -5 -g 24856 //24856进程的所有线程nice都设置为-5

综上,linux调度算法过程:

1.首先执行SCHECH_RR/SCHECH_FIFO进程,待他们执行到睡眠或者熔断,CPU切换到普通线程;

2.普通线程按CFS算法调度,在普通线程间轮转;

线程调度优先与线程是否在内核态无关,只由优先级和策略决定。用户态内核态只涉及权限问题;

关于CFS实现细节,参考多年前的一篇文章
http://blog.chinaunix.net/uid-24708340-id-3787960.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值