技术开发 频道

CPU负载平衡之--运行队列的load计算

  现在分析下这个公式;

  假设级别为i(0~4),运行队列的load值M,计算前的cpu_load[i] = mi,则每次的计算新的cpu_load[i] 遵循如下规律:

  cpu_load[i] = (M-mi)/2^i + mi

  I = 0~4 的情况下,此公式可扩展为:

  i=0: M - mi + mi

  i=1: (M - mi)/2 + mi

  i=2: (M-mi)/4 + mi

  i=3: (M-mi)/8 + mi

  i=4: (M-mi)/16 + mi

  由此可见,在M遵循上面的变化趋势下,等级为0的变化最为剧烈。

  另外,如果运行队列的load值比当前cpu_load[]的值大,会对M的值有个补偿:举这样一个例子, 假如M - mi = 17,对于计算i=4,来说,17/16 = 1,余数为1 ,这样太浪费了,我要把余数也计算进来,所以我要在M-mi处理时, 加上(16-1),这样,就不会浪费余数了。一句话:Round Up。

  具体在系统中这个函数是如何变化的呢? 可以在终端看下: cat /proc/sched_debu,可以看到不同cpu的相应数值.我的pc有两 个cpu,它们相应的与此函数相关的数据如下;

  cpu#0, 2705.784 MHz

  .nr_running : 2

  .load : 2048

  .nr_load_updates : 6651134

  .cpu_load[0] : 1024

  .cpu_load[1] : 576

  .cpu_load[2] : 364

  .cpu_load[3] : 214

  .cpu_load[4] : 124

  ...

  cpu#1, 2705.784 MHz

  .nr_running : 0

  .load : 0

  .nr_load_updates : 6846119

  .cpu_load[0] : 0

  .cpu_load[1] : 0

  .cpu_load[2] : 15

  .cpu_load[3] : 61

  .cpu_load[4] : 110

  现在我在此函数里加一些调试信息,看它在系统boot 过程中的变化,借此总结出此函数的变化趋势。 我加了一些调试信息,新的函数如下:

1 static void update_cpu_load(struct rq *this_rq)
2 {
3         unsigned long this_load = this_rq->load.weight;
4         int i, scale;
5
6         this_rq->nr_load_updates++;
7         printk("Before calculate: %d\n", this_load);   //在调用此函数时,打印当前运行队列的负载
8         /* Update our load: */
9         for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
10                 unsigned long old_load, new_load;
11
12                 /* scale is effectively 1 << i now, and >> i divides by scale */
13
14                 old_load = this_rq->cpu_load;
15                 new_load = this_load;
16                 /*
17                  * Round up the averaging division if load is increasing. This
18                  * prevents us from getting stuck on 9 if the load is 10, for
19                  * example.
20                  */
21                 if (new_load > old_load)
22                         new_load += scale-1;
23                 this_rq->cpu_load = (old_load*(scale-1) + new_load) >> i;
24                 printk(KERN_INFO "old_load = %d,this_rq->cpu_load[%d] = %d, new_load
25 = %d\n",old_load, i, this_rq->cpu_load, new_load);
26             //这儿我分别打印了更新前的 cpu_load,更新后的cpu_load,补偿后的运行队列负载
27         }
28
29 }
30
0
相关文章