ule调度(1)之交互性评分与优先级

交互性评分与优先级

Freebsd的ULE调度,采用了与Linux不同的思想。它采用了优先级比较的方式,目的是改善交互式进程的响应。

ULE主要是从线程的行为来识别该线程是否是交互式进程:一般交互式进程都是在等待输入事件,当获取到输入事件后进行相应的处理,最后再进入到输入事件等待中。这种等待事件-处理事件的特征,其时在现代的程序中都在使用,尤其是一些守护进程/后台服务都是在等待客户进程发送任务请求。唯一不同的是:在获取到输入事件后交互式进程的处理过程一般都很短,所以在ULE调度中就采用了主动睡眠时间/工作时间的比值来计算交互性评估,然后再将该评分换算成进程的优先级。

交互性评分算法

  • 当线程的睡眠时间大于运行时间时:

交互性评分 = 比例因子 睡眠时间 / 运行时间 交互性评分 = \frac{比例因子}{睡眠时间/运行时间} 交互性评分=睡眠时间/运行时间比例因子

  • 当线程的睡眠时间小于运行时间时:

交互性评分 = 比例因子 运行时间 / 睡眠时间 + 比例因子 交互性评分 = \frac{比例因子}{运行时间/睡眠时间} + 比例因子 交互性评分=运行时间/睡眠时间比例因子+比例因子

  • 当线程的睡眠时间等于运行时间,且都不为0时:

交互性评分 = 50 交互性评分 = 50 交互性评分=50

  • 当线程的睡眠时间等于运行时间,且都为 0时:

交互性评分 = 0 交互性评分 = 0 交互性评分=0

该算法使用睡眠时间与工作时间的比值来作为交互性判定,并通过比例因子归一化到 [ 0 : 100 ] [0:100] [0:100]之间。

交互评分换算成优先级

  • 当评分小于域值的时候

优先级 = 最小交互性优先级 + 交互性优先级范围 × 交互性评分 交互性域值 优先级 = 最小交互性优先级 + 交互性优先级范围 \times \frac{交互性评分}{交互性域值} 优先级=最小交互性优先级+交互性优先级范围×交互性域值交互性评分

  • 当评分大于等于域值的时候

优先级 = 基础优先级 + 累积运行时间 线程存在时间 × 优先级范围 + n i c e 优先级 = 基础优先级 + \frac{累积运行时间}{线程存在时间} \times 优先级范围 + nice 优先级=基础优先级+线程存在时间累积运行时间×优先级范围+nice

数据约束

  1. 交互性时间更新

在 FreeBSD 系统中使用睡眠时间和工作时间的比值来计算交互性评分。为了防止出现交互性评分过大过小的情况,系统使用 SCHED_SLP_RUN_MAX 对历史调度记录做了最大限制。

  • 当睡眠时间和工作时间总和小于 SCHED_SLP_RUN_MAX 时:

​ 不做任何处理

  • 当睡眠时间和工作时间总和大于 SCHED_SLP_RUN_MAX 时:

工作时间 = 工作时间 5 × 4 工作时间 = \frac{工作时间}{5} \times 4 工作时间=5工作时间×4

睡眠时间 = 睡眠时间 5 × 4 睡眠时间 = \frac{睡眠时间}{5} \times 4 睡眠时间=5睡眠时间×4

  • 当睡眠时间和工作时间总和大于 1.2 倍的 SCHED_SLP_RUN_MAX 时:

工作时间 = 工作时间 2 工作时间 = \frac{工作时间}{2} 工作时间=2工作时间

睡眠时间 = 睡眠时间 2 睡眠时间 = \frac{睡眠时间}{2} 睡眠时间=2睡眠时间

  • 当睡眠时间和工作时间总和大于 2 倍的 SCHED_SLP_RUN_MAX 时:

    • 运行时间 大于 睡眠时间:
      工作时间 = S C H E D _ S L P _ R U N _ M A X 工作时间 = SCHED\_SLP\_RUN\_MAX 工作时间=SCHED_SLP_RUN_MAX

      睡眠时间 = 1 睡眠时间 = 1 睡眠时间=1

    • 运行时间 小于等于 睡眠时间:

工作时间 = 1 工作时间 = 1 工作时间=1

睡眠时间 = S C H E D _ S L P _ R U N _ M A X 睡眠时间 = SCHED\_SLP\_RUN\_MAX 睡眠时间=SCHED_SLP_RUN_MAX

  1. CPU 利用率评估更新

在 FreeBSD 中使用累积运行时间和线程存在时间的比值来定义 CPU 的利用率。为了防止出现利用率过大/过小的情况,系统又定义了线程一次过程最大计时时间 SCHED_TICK_TARG 和线程持续运行最大计时时间 SCHED_TICK_MAX

  • 当一次过程大于等于 SCHED_TICK_TARG 时:

    • 复位累积运行时间;
    • 重新设置线程开始时间;
  • 当持续运行时间大于等于 SCHED_TICK_MAX 时:

    • 累计运行时间:
      累积运行时间 = 上次测量的累积运行时间 上次测量的存在时间 × (本地运行时间 + S C H E D _ T I C K _ T A R G ) 累积运行时间 = \frac{上次测量的累积运行时间}{上次测量的存在时间} \times (本地运行时间 + SCHED\_TICK\_TARG) 累积运行时间=上次测量的存在时间上次测量的累积运行时间×(本地运行时间+SCHED_TICK_TARG

    • 重新设置线程开始时间;

当线程处于运行态,则累积运行时间:
累积运行时间 = 上次累积运行时间 + 本次运行时间 累积运行时间 = 上次累积运行时间 + 本次运行时间 累积运行时间=上次累积运行时间+本次运行时间

总结

从上面可以看出,运行时间越长、随眠时间越短优先级越低。
其时这里我觉得 ULE 调度其时是改善了程序的响应速度,并不单单针对交互式进程;而那些长期占用 CPU 资源的程序会遭到惩罚——降低优先级从而减少运行的时间。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值