• 调度器30—调度相关结构体—struct sched_entity Hello


    一、struct sched_entity

    1. se->sum_exec_runtime

    表示实际running的时间,不包括runnable时间。

    (1) sum_exec_runtime 的更新逻辑

    void set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
    {
        ...
        update_stats_curr_start(cfs_rq, se);
        /* 选中当前se去运行 */
        cfs_rq->curr = se;
        ...
        /* 新的一次运行开始的时候才将sum值赋值给prev_sum */
        se->prev_sum_exec_runtime = se->sum_exec_runtime;
    }
    
    static inline void update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
    {
        /* We are starting a new run period:*/
        se->exec_start = rq_clock_task(rq_of(cfs_rq)); //return rq->clock_task;
    }
    
    static void update_curr(struct cfs_rq *cfs_rq)
    {
        struct sched_entity *curr = cfs_rq->curr;
        u64 now = rq_clock_task(rq_of(cfs_rq));
        u64 delta_exec;
        ...
        
        /* 在核间迁移时,调整的是 exec_start, sum_exec_runtime 是单调累加的,核间迁移也不影响 */
        delta_exec = now - curr->exec_start;
        ...
        curr->exec_start = now;
        ...
        /* 更新任务累计的运行时间 */
        curr->sum_exec_runtime += delta_exec;
    
        /* 更新 se 的虚拟时间 */
        curr->vruntime += calc_delta_fair(delta_exec, curr);
        update_min_vruntime(cfs_rq);
        ...
    }

    (2) 实验

    # echo lock > /sys/power/wake_lock
    
    //搞5个死循环,掐秒表10s
    # let i=0; while true; do let i=i+1; done &
    //5个死循环绑定cpu1
    # taskset -p 01 24961
    
    10测试前:
    # for P in 24937 24940 24946 24955 24961; do cat /proc/$P/sched | grep se.sum_exec_runtime; done;
    se.sum_exec_runtime                          :         59548.030554
    se.sum_exec_runtime                          :         43598.199964
    se.sum_exec_runtime                          :         38325.025722
    se.sum_exec_runtime                          :         31508.426646
    se.sum_exec_runtime                          :         28923.228260
    10测试后:
    # for P in 24937 24940 24946 24955 24961; do cat /proc/$P/sched | grep se.sum_exec_runtime; done;
    se.sum_exec_runtime                          :         61571.478979
    se.sum_exec_runtime                          :         45617.150613
    se.sum_exec_runtime                          :         40347.151159
    se.sum_exec_runtime                          :         33529.815536
    se.sum_exec_runtime                          :         30944.450859
    
    10s后        10s前        delta
    61571.47898    59548.03055    2023.448425
    45617.15061    43598.19996    2018.950649
    40347.15116    38325.02572    2022.125437
    33529.81554    31508.42665    2021.38889
    30944.45086    28923.22826    2021.222599

    可以看到,统计到的每个进程的运行时间是2s,而不是10s,验证了的确是运行时间不包括runnable时间。

    2. se->vruntime

    vruntime 主要在 update_curr() 中进行更新,每次都是加上执行时间在自己权重上映射得到的虚拟时间。在任务迁移时,迁移的是 se->vruntime -= cfs_rq->min_vruntime, 迁移到新CPU后恢复的是 se->vruntime += cfs_rq->min_vruntime。在任务唤醒时,或唤醒的是休眠的任务则会进行虚拟时间补偿,若唤醒的是新fork出来的任务,则会进行虚拟时间惩罚,见place_entity()。

    除此之外,虚拟时间没有其它额外更新路径!

  • 相关阅读:
    HDU 4436 str2int (后缀自动机SAM,多串建立)
    HDU 4498 Function Curve (自适应simpson)
    PHP实现微信商户支付企业付款到零钱功能代码实例
    微信支付现金红包接口应用实例代码说明和DEMO详解,适合用来做微信红包营销活动、吸粉利器
    java开发学生信息管理系统的实现(简洁易懂),适合计算机专业学生参考,课程设计、毕业论文设计参考等
    公司注册经营范围大全
    《胡雪岩》影评10篇
    提高淘宝店铺动态评分的四大技巧
    为什么我的淘宝店铺动态评分清零了?
    CC攻击原理及防范方法和如何防范CC攻击
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/16512917.html
Copyright © 2020-2023  润新知