CFS完全公平调度算法
来源:互联网 发布:windows clean up官网 编辑:程序博客网 时间:2024/04/29 03:23
struct sched_avg {
/*
* These sums represent an infinite geometric series and so are bound
* above by 1024/(1-y). Thus we only need a u32 to store them for all
* choices of y < 1-2^(-32)*1024.
*/
u32 runnable_avg_sum, runnable_avg_period; /* 前一个:调度实体累计负载均衡值(不包括未进入运行队列期间的负载均衡值);后一个:调度实体累计负载均衡值*/
u64 last_runnable_update; /* 最近一次更新负载均衡值的时间,用ns表示 */
s64 decay_count; /* 衰减次数 */
unsigned long load_avg_contrib; /* 该调度实体对它所属的CFS_RQ队列的负载均衡贡献值 */
};
调度实体的负载均衡值周期性的被更新,由__update_entity_runnable_avg()函数实际执行该操作。struct sched_avg用于跟踪调度实体的负载变更情况。
/*
* These sums represent an infinite geometric series and so are bound
* above by 1024/(1-y). Thus we only need a u32 to store them for all
* choices of y < 1-2^(-32)*1024.
*/
u32 runnable_avg_sum, runnable_avg_period; /* 前一个:调度实体累计负载均衡值(不包括未进入运行队列期间的负载均衡值);后一个:调度实体累计负载均衡值*/
u64 last_runnable_update; /* 最近一次更新负载均衡值的时间,用ns表示 */
s64 decay_count; /* 衰减次数 */
unsigned long load_avg_contrib; /* 该调度实体对它所属的CFS_RQ队列的负载均衡贡献值 */
};
调度实体的负载均衡值周期性的被更新,由__update_entity_runnable_avg()函数实际执行该操作。struct sched_avg用于跟踪调度实体的负载变更情况。
* We can represent the historical contribution to runnable average as the * coefficients of a geometric series. To do this we sub-divide our runnable * history into segments of approximately 1ms (1024us); label the segment that * occurred N-ms ago p_N, with p_0 corresponding to the current period, e.g. * * [<- 1024us ->|<- 1024us ->|<- 1024us ->| ... * p0 p1 p2 * (now) (~1ms ago) (~2ms ago) * * Let u_i denote the fraction of p_i that the entity was runnable. * * We then designate the fractions u_i as our co-efficients, yielding the * following representation of historical load: * u_0 + u_1*y + u_2*y^2 + u_3*y^3 + ... * * We choose y based on the with of a reasonably scheduling period, fixing: * y^32 = 0.5 * * This means that the contribution to load ~32ms ago (u_32) will be weighted * approximately half as much as the contribution to load within the last ms * (u_0). * * When a period "rolls over" and we have new u_0`, multiplying the previous * sum again by y is sufficient to update: * load_avg = u_0` + y*(u_0 + u_1*y + u_2*y^2 + ... ) * = u_0 + u_1*y + u_2*y^2 + ... [re-labeling u_i --> u_{i+1}] */static __always_inline int __update_entity_runnable_avg(u64 now, struct sched_avg *sa, int runnable){ u64 delta, periods; u32 runnable_contrib; int delta_w, decayed = 0; delta = now - sa->last_runnable_update; /* 计算新采样周期的值 */ /* * This should only happen when time goes backwards, which it * unfortunately does during sched clock init when we swap over to TSC. */ if ((s64)delta < 0) { sa->last_runnable_update = now; return 0; } /* * Use 1024ns as the unit of measurement since it's a reasonable * approximation of 1us and fast to compute. */ delta >>= 10; /* 把周期值由ns转化为us */ if (!delta) return 0; sa->last_runnable_update = now; /* 记录负载均衡值更新的最新时间点 */ /* delta_w is the amount already accumulated against our next period */ delta_w = sa->runnable_avg_period % 1024; /* 历史负载均衡值对齐到1024us的偏移量 */ if (delta + delta_w >= 1024) { /* 自从上一次更新负载均衡值后,已至少累计了1024us时间(上次未对齐到1024us偏移量加上本次更新周期值) */ /* period roll-over */ decayed = 1; /* 返回历史负载均衡衰减状态 */ /* * Now that we know we're crossing a period boundary, figure * out how much from delta we need to complete the current * period and accrue it. */ delta_w = 1024 - delta_w; if (runnable) sa->runnable_avg_sum += delta_w; /* 如果该调度实体在运行队列上,则更新runnable_avg_sum值 */ sa->runnable_avg_period += delta_w; delta -= delta_w; /* Figure out how many additional periods this update spans */ periods = delta / 1024; /* 针对本次采样周期内剩余时间的负载均衡值计算,分别先算出计算周期数和1024us遗留偏移 */ delta %= 1024; sa->runnable_avg_sum = decay_load(sa->runnable_avg_sum, periods + 1); /* 对历史累计负载均衡值进行衰减处理,得到当前时间等效的历史累计负载均衡值 */ sa->runnable_avg_period = decay_load(sa->runnable_avg_period, periods + 1); /* 同上 */ /* Efficiently calculate \sum (1..n_period) 1024*y^i */ runnable_contrib = __compute_runnable_contrib(periods); /* 计算本次采样周期折算计算周期数对负载均衡值的贡献值 */ if (runnable) sa->runnable_avg_sum += runnable_contrib; sa->runnable_avg_period += runnable_contrib; /* 累加历史负载均衡值和本次获得的负载均衡值 */ } /* Remainder of delta accrued against u_0` */ if (runnable) sa->runnable_avg_sum += delta; sa->runnable_avg_period += delta; /* 当前总的负载均衡值还要加上未满1024us的剩余时间,这些时间不做衰减处理 */ return decayed;}
0 0
- CFS完全公平调度算法
- Linux的CFS(完全公平调度)算法
- CFS(完全公平调度算法)
- cfs 完全公平调度
- 完全公平调度-cfs
- 完全公平调度(CFS)
- CFS完全公平调度类
- Linux进程调度算法,不同的调度策略、实时性,完全公平调度算法CFS
- linux中O(1)调度算法与完全公平(CFS)调度算法
- linux中O(1)调度算法与完全公平(CFS)调度算法
- linux内核进程调度CFS 完全公平调度算法分析(一)
- CFS完全公平调度算法 - per entity load tracking 几个重要的函数分析
- Linux 2.6 完全公平调度算法CFS(Completely Fair Scheduler)分析
- linux内核分析——CFS(完全公平调度算法)
- linux内核分析——CFS(完全公平调度算法)
- linux内核分析——CFS(完全公平调度算法)
- 进程调度子系统(3)完全公平调度类CFS
- linux 2.6 CFS完全公平调度器内幕
- 想象力测试看看你的情商有多高(不要做一个冷血的人哦~)
- 6 个重构方法可帮你提升 80% 的代码质量
- c#数组的应用
- Valid Sudoku
- c++指针和引用的区别
- CFS完全公平调度算法
- Android开发之ListView中Adapter的优化
- maven(四) 依赖关系
- foreach
- android四大组件之Service
- Median of Two Sorted Arrays
- leetcode reorder-list
- Maven仓库
- 2014.11.26二分查找