【WALT】WALT入口 update_task_ravg() 代码详解

代码版本:Linux4.9 android-msm-crosshatch-4.9-android12

代码展示

void update_task_ravg(struct task_struct *p, struct rq *rq, int event,
u64 wallclock, u64 irqtime) {
u64 old_window_start; // ⑴ 判断是否进入 WALT 算法
if (!rq->window_start || sched_disable_window_stats ||
p->ravg.mark_start == wallclock)
return; lockdep_assert_held(&rq->lock); // ⑵ 获取 WALT 算法中上一个窗口的开始时间
old_window_start = update_window_start(rq, wallclock, event); // ⑶ 如果任务刚初始化结束,不进入 WALT 算法,进入 `done`
if (!p->ravg.mark_start) {
update_task_cpu_cycles(p, cpu_of(rq), wallclock);
goto done;
} // ⑷ 更新任务及 CPU 的 cycles
update_task_rq_cpu_cycles(p, rq, event, wallclock, irqtime);
// ⑸ 更新任务及 CPU 的 demand 及 pred_demand
update_task_demand(p, rq, event, wallclock);
// ⑹ 更新 CPU 的 busy time
update_cpu_busy_time(p, rq, event, wallclock, irqtime);
// ⑺ 更新任务的 pred_demand
update_task_pred_demand(rq, p, event); // ⑻ 如果任务正在退出,进入 `done`
if (exiting_task(p))
goto done; // 两个系统自带的 tracepoint
trace_sched_update_task_ravg(p, rq, event, wallclock, irqtime,
rq->cc.cycles, rq->cc.time, &rq->grp_time);
trace_sched_update_task_ravg_mini(p, rq, event, wallclock, irqtime,
rq->cc.cycles, rq->cc.time, &rq->grp_time); done:
p->ravg.mark_start = wallclock;
run_walt_irq_work(old_window_start, rq);
}

代码逻辑

WALT 算法以任务为主,当任务被唤醒、任务开始执行、任务停止执行、任务退出、窗口滚动、频率变化、任务迁移、经过一个调度tick、在中断结束时会调用update_task_ravg()

其中,窗口是 WALT 算法中的一个特殊的设定,将在 update_task_demand()update_cpu_busy_time() 中详细解释。

⑴ 判断是否进入 WALT 算法

在进入 WALT 算法后首先会判断当前任务所在的运行队列(runqueue)是否进行初始化,以及是否禁用 CPU 的窗口统计:if(!rq->window_start || sched_disable_window_stats...)。如果没有初始化,就不会记录窗口的开始时间,任务负载就无法进行计算。有几点需要注意:

  1. 该处是指 rq,而非 cfs->rq 或 rt->rq,即该处不区分实时任务或普通任务;
  2. 任务/CPU 窗口(sched_ravg_window)是自定义的,不同版本代码或不同设备中设置的窗口大小是不一样的,调整的位置也不尽相同。

然后会判断窗口开始时间是否更新:if(...p->ravg.mark_start == wallclock)。如果运行队列没有初始化,或禁用了 CPU 的窗口统计,或窗口开始时间没有更新,就会直接结束 WALT 算法。

⑵ 获取 WALT 算法中上一个窗口的开始时间

然后通过函数update_window_start()获取上一个窗口的开始时间,存在变量old_window_start中。

点击此处查看 update_window_start() 代码详解。

⑶ 如果任务刚初始化结束

如果任务刚初始化结束:if(!p->ravg.mark_start),还没有标记过任务的开始时间,就先通过函数 update_task_cpu_cycles() 更新一下该任务的 cycles 值(p->cpu_cycles),然后进入 done

点击此处查看 update_task_cpu_cycles() 代码详解。

⑷ 更新任务及 CPU 的 cycles

update_task_cpu_cycles() 相似,但比其多更新了 CPU 的 cycles 值(rq->cc.cycles)。

点击此处查看 update_task_rq_cpu_cycles() 代码详解。

⑸ 更新任务及 CPU 的 demand 及 pred_demand

在任务满足条件后,在不同情况下根据任务的开始时间、窗口的开始时间以及当前时间来计算任务在当前及之前M个窗口中的运行时间。在窗口结束时将运行时间进行归一化,并统计进任务的历史窗口中(sum_history[RAVG_HIST_SIZE])。

WALT 算法根据历史窗口中的值计算任务的 demand,根据桶算法计算任务的 pred_demand,并将 demand 与 pred_demand 统计进任务所在 CPU 的 rq(runqueue)中。

注意:以上说的 demand 与 pred_demand 都是预测值。

点击此处查看 update_task_demand() 代码详解。

⑹ 更新 CPU 的 busy time

在任务满足条件后,在不同情况下根据任务的开始时间、窗口的开始时间以及当前时间来计算任务在当前及上一个窗口中的运行时间,将不同窗口内的运行时间进行归一化,并根据任务的状态统计进任务的 curr_windowprev_window 中,以及任务所在 rq 的 curr_runnable_sumprev_runnable_sum 中。

在窗口翻滚的时候更新任务的 window 值 以及 rq 的 runnable_sum 的值。

注意:以上说的 window 以及 runnable_sum 都是真实值。

点击此处查看 update_cpu_busy_time() 代码详解。

⑺ 更新任务的 pred_demand

如果符合条件的任务在当前窗口中预测出来的 demand 值小于 curr_window,则再次使用桶算法计算 pred_demand。

点击此处查看 update_task_pred_demand() 代码详解。

⑻ 如果任务正在退出

#define EXITING_TASK_MARKER	0xdeaddead

static inline int exiting_task(struct task_struct *p)
{
return (p->ravg.sum_history[0] == EXITING_TASK_MARKER);
}

当任务最近一个窗口的值为 0xdeaddead 时,意味着任务正在退出,进入 done

done 结束部分:

  1. 更新一下任务的开始时间:p->ravg.mark_start = wallclock
  2. 通过函数 irq_work_queue() 处理没有 tick 的情况,循环调用 update_task_ravg()

【WALT】WALT入口 update_task_ravg() 代码详解的更多相关文章

  1. ARM Cortex-M底层技术(2)—启动代码详解

    杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第 ...

  2. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  3. ASP.NET MVC 5 学习教程:生成的代码详解

    原文 ASP.NET MVC 5 学习教程:生成的代码详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...

  4. Github-karpathy/char-rnn代码详解

    Github-karpathy/char-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan  2016-1-10 ...

  5. 代码详解:TensorFlow Core带你探索深度神经网络“黑匣子”

    来源商业新知网,原标题:代码详解:TensorFlow Core带你探索深度神经网络“黑匣子” 想学TensorFlow?先从低阶API开始吧~某种程度而言,它能够帮助我们更好地理解Tensorflo ...

  6. JAVA类与类之间的全部关系简述+代码详解

    本文转自: https://blog.csdn.net/wq6ylg08/article/details/81092056类和类之间关系包括了 is a,has a, use a三种关系(1)is a ...

  7. Java中String的intern方法,javap&cfr.jar反编译,javap反编译后二进制指令代码详解,Java8常量池的位置

    一个例子 public class TestString{ public static void main(String[] args){ String a = "a"; Stri ...

  8. Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测

    Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测 2017年12月13日 17:39:11 机器之心V 阅读数:5931   近日,Artur Suilin 等人发布了 Kaggl ...

  9. 基础 | batchnorm原理及代码详解

    https://blog.csdn.net/qq_25737169/article/details/79048516 https://www.cnblogs.com/bonelee/p/8528722 ...

  10. 非极大值抑制(NMS,Non-Maximum Suppression)的原理与代码详解

    1.NMS的原理 NMS(Non-Maximum Suppression)算法本质是搜索局部极大值,抑制非极大值元素.NMS就是需要根据score矩阵和region的坐标信息,从中找到置信度比较高的b ...

随机推荐

  1. 【Dotnet 工具箱】跨平台图表库 LiveCharts2

    你好,这里是 Dotnet 工具箱,定期分享 Dotnet 有趣,实用的工具和组件,希望对您有用! LiveCharts2 LiveCharts2 是一个简单.灵活.交互式以及功能强大的跨平台图表库. ...

  2. Solon2 常用注解之 @Component 与 @ProxyComponent 的区别

    在 Solon 提倡"克制"的原则下,托管组件分为: 普通组件: 主要由内核提供的:@Configuration.@Component.@Controller.@Remoting ...

  3. Python实现网络工具

    使用python编写网络工具 基础内容 介绍基本的网络编程 Socket编程 Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请 ...

  4. ArrayList实现原理和自动扩容

    ArrayList在Java集合中的位置, ArrayList原理: transient Object[] elementData; ArrayList通过数组来实现. 默认构造方法会构造一个容量为1 ...

  5. AspNetCore 成长杂记(一):JWT授权鉴权之生成JWT(其二)

    引子 前面说了用第三方类库生成JWT的故事,给我带来了很大的方便,并且我也承诺要写一篇用常规方法生成JWT的文章(一般都是用微软官方的类库),因此才有了这篇文章. 另外,在前面的文章中,我要纠正一下一 ...

  6. [Pytorch框架] 2.3 神经网络简介

    文章目录 2.3 神经网络简介 概述 神经网络的表示 激活函数 为什么激活函数都是非线性的 sigmod 函数 tanh 函数 ReLU 函数 Leaky Relu 函数 深入理解前向传播和反向传播 ...

  7. ubuntu20安装docker、redis、mysql及部署net6应用

    一.更新系统软件包索引 sudo apt update 二.安装docker sudo apt install docker.io 三.在docker中安装Mysql 拉取mysql镜像 docker ...

  8. 2023-05-07:给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。 返回执行此操作后,grid 中最大的岛屿面积是多少? 岛屿 由一组上、下、左、右四个方向相

    2023-05-07:给你一个大小为 n x n 二进制矩阵 grid .最多 只能将一格 0 变成 1 . 返回执行此操作后,grid 中最大的岛屿面积是多少? 岛屿 由一组上.下.左.右四个方向相 ...

  9. 2023-03-24:音视频mp3和h264混合(muxer)编码为mp4,用go语言编写。

    2023-03-24:音视频mp3和h264混合(muxer)编码为mp4,用go语言编写. 答案2023-03-24: 这是一个使用FFmpeg库将MP3和H.264混合编码为MP4的Go语言程序. ...

  10. 浅谈如何使用 github.com/yuin/gopher-lua

    最近熟悉 go 项目时,发现项目中有用到 github.com/yuin/gopher-lua这个包,之前并没有接触过,特意去看了官方文档和找了些网上的资料,特此记录下. 本次介绍计划分为两篇文章,这 ...