Chinaunix首页 | 论坛 | 博客
  • 博客访问: 33543
  • 博文数量: 5
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 71
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-02 21:05
文章分类
文章存档

2014年(5)

我的朋友

分类: LINUX

2014-05-22 09:21:30

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用于跟踪调度实体的负载变更情况。

点击(此处)折叠或打开

  1.     
  2.  * We can represent the historical contribution to runnable average as the
  3.  * coefficients of a geometric series. To do this we sub-divide our runnable
  4.  * history into segments of approximately 1ms (1024us); label the segment that
  5.  * occurred N-ms ago p_N, with p_0 corresponding to the current period, e.g.
  6.  *
  7.  * [<- 1024us ->|<- 1024us ->|<- 1024us ->| ...
  8.  * p0 p1 p2
  9.  * (now) (~1ms ago) (~2ms ago)
  10.  *
  11.  * Let u_i denote the fraction of p_i that the entity was runnable.
  12.  *
  13.  * We then designate the fractions u_i as our co-efficients, yielding the
  14.  * following representation of historical load:
  15.  * u_0 + u_1*y + u_2*y^2 + u_3*y^3 + ...
  16.  *
  17.  * We choose y based on the with of a reasonably scheduling period, fixing:
  18.  * y^32 = 0.5
  19.  *
  20.  * This means that the contribution to load ~32ms ago (u_32) will be weighted
  21.  * approximately half as much as the contribution to load within the last ms
  22.  * (u_0).
  23.  *
  24.  * When a period "rolls over" and we have new u_0`, multiplying the previous
  25.  * sum again by y is sufficient to update:
  26.  * load_avg = u_0` + y*(u_0 + u_1*y + u_2*y^2 + ... )
  27.  * = u_0 + u_1*y + u_2*y^2 + ... [re-labeling u_i --> u_{i+1}]
  28.  */
  29. static __always_inline int __update_entity_runnable_avg(u64 now,
  30.                             struct sched_avg *sa,
  31.                             int runnable)
  32. {
  33.     u64 delta, periods;
  34.     u32 runnable_contrib;
  35.     int delta_w, decayed = 0;

  36.     delta = now - sa->last_runnable_update;    /* 计算新采样周期的值 */

  37.     /*
  38.      * This should only happen when time goes backwards, which it
  39.      * unfortunately does during sched clock init when we swap over to TSC.
  40.      */
  41.     if ((s64)delta < 0) {
  42.         sa->last_runnable_update = now;
  43.         return 0;
  44.     }

  45.     /*
  46.      * Use 1024ns as the unit of measurement since it's a reasonable
  47.      * approximation of 1us and fast to compute.
  48.      */
  49.     delta >>= 10;    /* 把周期值由ns转化为us */

  50.     if (!delta)
  51.         return 0;
  52.     sa->last_runnable_update = now;  /* 记录负载均衡值更新的最新时间点 */

  53.     /* delta_w is the amount already accumulated against our next period */
  54.     delta_w = sa->runnable_avg_period % 1024;  /* 历史负载均衡值对齐到1024us的偏移量 */

  55.     if (delta + delta_w >= 1024) {   /* 自从上一次更新负载均衡值后,已至少累计了1024us时间(上次未对齐到1024us偏移量加上本次更新周期值) */

  56.         /* period roll-over */
  57.         decayed = 1;  /* 返回历史负载均衡衰减状态 */

  58.         /*
  59.          * Now that we know we're crossing a period boundary, figure
  60.          * out how much from delta we need to complete the current
  61.          * period and accrue it.
  62.          */
  63.         delta_w = 1024 - delta_w;
  64.         if (runnable)
  65.             sa->runnable_avg_sum += delta_w;  /* 如果该调度实体在运行队列上,则更新runnable_avg_sum值 */
  66.         sa->runnable_avg_period += delta_w;

  67.         delta -= delta_w;

  68.         /* Figure out how many additional periods this update spans */
  69.         periods = delta / 1024;  /* 针对本次采样周期内剩余时间的负载均衡值计算,分别先算出计算周期数和1024us遗留偏移 */

  70.         delta %= 1024;

  71.         sa->runnable_avg_sum = decay_load(sa->runnable_avg_sum,
  72.                          periods + 1);  /* 对历史累计负载均衡值进行衰减处理,得到当前时间等效的历史累计负载均衡值 */
  73.         sa->runnable_avg_period = decay_load(sa->runnable_avg_period,
  74.                          periods + 1);  /* 同上 */

  75.         /* Efficiently calculate \sum (1..n_period) 1024*y^i */
  76.         runnable_contrib = __compute_runnable_contrib(periods);  /* 计算本次采样周期折算计算周期数对负载均衡值的贡献值 */

  77.         if (runnable)
  78.             sa->runnable_avg_sum += runnable_contrib;
  79.         sa->runnable_avg_period += runnable_contrib;  /* 累加历史负载均衡值和本次获得的负载均衡值 */

  80.     }

  81.     /* Remainder of delta accrued against u_0` */
  82.     if (runnable)
  83.         sa->runnable_avg_sum += delta;
  84.     sa->runnable_avg_period += delta;   /* 当前总的负载均衡值还要加上未满1024us的剩余时间,这些时间不做衰减处理 */

  85.     return decayed;
  86. }
阅读(4115) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:struct cfs_rq结构体成员解析

给主人留下些什么吧!~~