pelt

news/2024/12/25 0:44:07/文章来源:https://www.cnblogs.com/xingxingx/p/18628981

为什么需要PELT?

之前CFS以每个运行队列为单位跟踪负载;存在几个问题:

  • 一个运行队列存在很多个调度实体,所以无法存在当前的负载来源;
  • 即使工作负载相对稳定的情况下,在rq级别跟踪负载,其值也会产生很大变化。(为什么?)

为了解决以上问题:提出了PETL算法,PELT算法跟踪每个调度实体

如何进行PELT

  • 时间(物理时间,不是虚拟时间)被分成了1024us的序列(以1024us为单位划分)
  • 在每一个1024us的周期中(注意这里是一个周期),一个entity对系统负载的贡献可以根据该实体处于runnable状态(正在CPU上运行或者等待cpu调度运行)的时间进行计算。(负载就是runable的时间占比)
  • 比如:该entity在该周期内,runnable的时间是x,那么对系统负载的贡献就是(x/1024);
  • 一个实体在一个计算周期内(注意是计算周期,有多个1024us)的负载可能会超过1024us(这里以us时间为单位的原因是负载就是runable时间的比值),这是因为我们会累积在过去周期中的负载。当然,对于过去的负载我们在计算的时候需要乘一个衰减因子
  • 如果我们让Li表示在周期pi中该调度实体的对系统负载贡献,那么一个调度实体对系统负荷的总贡献可以表示为:
    L = L0 + L1 * y + L2 * y2 + L3 * y3 + ... + Ln * yn
    y32 = 0.5, y = 0.97857206

如何计算第n个周期的衰减值?

  • 内核提供decay_load()函数用于计算第n个周期的衰减值;
  • 为了避免浮点数运算,采用移位和乘法运算提高计算速度:
    • decay_load(val, n) = val * y^n = val * y^n * 2^32 >> 32 = val * (y^n * 2^32) >> 32
    • 将 (y^n * 2^32) 的值提前计算好放入数组runnable_avg_yN_inv中;

如何计算当前负载贡献

某个时间点的负载u'过了p个周期后的负载值是多少?

  • 假如某个时间点的负载: u = xy^3 + 1024y^2 + 1024*y + x;
  • 相当于分为了四段;
    alt text
  • 过了p个周期之后,每一段负载变为:
    • x*y^3 * y^p
    • 1024*y^2 * y^p
    • 1024*y * y^p
    • x * y^p
  • u的负载是这四段之和,过了p个周期之后,u的负载是:xy^3 * y^p + 1024y^2 * y^p + 1024*y * y^p + x * y^p = u * y^p;
  • 也就是说u过了p个周期后的负载值是: u' * y^p

当前负载计算

           d1          d2           d3^           ^            ^|           |            ||<->|<----------------->|<--->|... |---x---|------| ... |------|-----x (now)p-1u' = (u + d1) y^p + 1024 \Sum y^n + d3 y^0n=1= u y^p +					(Step 1)p-1d1 y^p + 1024 \Sum y^n + d3 y^0		(Step 2)n=1

首先分为两大段:

  • (Step 1):计算历史负载u对当前负载的贡献u y^p
  • (Step 2):计算经过时间的负载贡献;
    • 假设时间d是经过p(就是完整的周期数+1)个周期(d=d1+d2+d3, p=1+d2/1024),把当前经过的时间分为了三段:
      • d1:d1是离当前时间最远(不完整的)period 的剩余部分
      • d2: 是完整period时间
      • d3: d3是(不完整的)当前 period 的剩余部分

代码实现

数据结构

第n个周期的负载

	if (unlikely(local_n >= LOAD_AVG_PERIOD)) {val >>= local_n / LOAD_AVG_PERIOD;	/* 左移一位表示除2,y^32=1/2,也就是左移一位相当于计算y^32;这里计算可以整除多少个32,也就是左移多少位; */local_n %= LOAD_AVG_PERIOD;}
  • y^32 = 1/2;
  • 左移一位表示除2;
  • 也就是左移一位相当于计算y^32
  • local_n / LOAD_AVG_PERIOD的值,表示可以整除多少个32,也就是左移多少位;
  • mul_u64_u32_shr 计算剩余部分的值; (u64)(((unsigned __int128)a * mul) >> shift);

累计负载计算代码实现

调度实体更新负载贡献

就绪队列更新负载信息

runnable_load_avg和load_avg区别

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/858441.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fork

dup_task_structsched_forkcopy_mmcopy_thread_tls

page_fault

预备处理do_page_faultdo_anonymous_pagedo_faultdo_wp_page

LangChain简单大模型应用

LangChain官方示例教程(Build a Simple LLM Application)。重新组织顺序及说明方式,更加适合新手阅读。LangChain官方示例教程(Build a Simple LLM Application):https://python.langchain.com/docs/tutorials/llm_chain/将该官方示例教程适当调整及优化依赖pip install lang…

Elasticsearch filter context 的实践案例

知识背景 在 ES 查询优化的建议里,很多时候为了避免算分逻辑和利用缓存逻辑,Elastic 会建议大家使用 filter 条件。 filter 的使用条件和原理具体可以参照之前写的博文《Elasticsearch filter context 的使用原理》 这里我们来研究 2 个实用案例,具体的感受一下 filter cont…

产品发展的六阶段

一个成熟的互联网产品从最初的创意到完全成熟,通常需要经历以下几个主要阶段。每个阶段都有特定的目标、核心任务和关键成果,以下是详细的解析。 一、创意阶段 1、创意阶段的核心目标 1.1 识别用户需求 创意阶段的首要任务是发现并明确目标用户的痛点和需求。通过市场调研、…

【unity]学习制作类银河恶魔城游戏-2-

导入新资产切割新资产切割完成修改大小和清晰度球体已经设置了刚体和碰撞体积,直接应用给人物,改名circle为player中心点问题 因为切割的原因,碰撞模型的中心点和人物的中心点不相吻合解决:在子路径下渲染人物图片,将二者的中心点手动对齐手动对齐保存更改更改碰撞体模型运…

DevNow x Notion

DevNow x Notion: DevNow 支持了 Notion 作为其文档系统,可以帮助用户在 Notion 更高效地管理文档,实现文档的集中管理和协作。前言 Notion 应该是目前用户量比较大的一个在线笔记软件,它的文档系统也非常完善,支持多种文档格式,如 Markdown、富文本、表格、公式等。 早期…

平安夜吃苹果

祝大家平安夜快乐 有一棵特殊的苹果树,一连 n 天,每天都可以长出若干个苹果。在第 i 天,树上会长出 apples[i] 个苹果,这些苹果将会在 days[i] 天后(也就是说,第 i + days[i] 天时)腐烂,变得无法食用。也可能有那么几天,树上不会长出新的苹果,此时用 apples[i] == 0 …

基于Three.js的大屏3D地图(一)

依赖安装 yarn add three yarn add @types/three yarn add d3-geothree库安装后在node_modules下其还包含核心three/src和插件three/example/jsm的源码,在开发调试时可以直接查阅。使用Three.js过程中会涉及到许多的类、方法及参数配置,所以建议安装@types/three库;不仅能提…

Java 变量和运算符

Java 变量和运算符1. 变量(Variable)1.1 何为变量 1.2 数据类型(Data Types)1.2.1 整型:byte、short、int、long 1.2.2 浮点类型:float、double 1.2.3 字符类型:char 1.2.4 布尔类型:boolean1.3 变量的使用1.3.1 步骤1:变量的声明 1.3.2 步骤2:变量的赋值1.4. 基本数…