zoukankan      html  css  js  c++  java
• # 调度器3—PELT算法下util_avg的增速和减速

这个程序用于 debug 若一个任务突然一直跑下去，其 util_avg 增加的速度。util_avg 是对一个正在运行的任务计算的，若其不允许了，对系统的 util 的影响应该是0，若是 n 个 periods(周期1024us) 后又开始运行了，其 uitl_avg 直接乘以 y^n 即可。

一、测试增速

1. 测试程序

```#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define HALFLIFE_32 32

#define HALFLIFE_8 8

#define HALFLIFE_4 4

#define HALFLIFE_3 3

#define HALFLIFE_2 2

void calc_converged_max(double y)
{
int n = -1;
/* first period */
long max = 1024;
long last = 0, y_inv = ((1UL << 32) - 1) * y;

for (; ; n++) {
if (n > -1) {
max = ((max * y_inv) >> 32) + 1024;
/* This is the same as: max = max*y + 1024; */
}
if (last == max)
break;

last = max;
}
n--;

", max);

", n);
}

int util_avg_from_sudden_running_all_time(double y, int periods, int load_avg_max) {
int i;
double util_avg;
double util_sum = 0;

for (i = 0; i < periods; i++) {
util_sum += 1024 * pow(y, i);

printf("util_sum=%d, periods=%d, util_avg=%%%d
", (int)util_sum, i+1, (int)(util_avg * 100));
}

return 0;
}

void main(int argc, char *argv[])
{
double y;
int choose = 32, periods = 200;

if (argc == 2) {
choose = atoi(argv[1]);
}

if (argc == 3) {
choose = atoi(argv[1]);
periods = atoi(argv[2]);
}

printf("y^%d=0.5, periods=%d
", choose, periods);

switch(choose) {
case 32:
y = pow(0.5, 1/(double)HALFLIFE_32);
calc_converged_max(y); //47742
break;
case 8:
y = pow(0.5, 1/(double)HALFLIFE_8);
calc_converged_max(y); //12326
break;
case 4:
y = pow(0.5, 1/(double)HALFLIFE_4);
calc_converged_max(y); //6430
break;
case 3:
y = pow(0.5, 1/(double)HALFLIFE_3);
calc_converged_max(y); //4959
break;
case 2:
y = pow(0.5, 1/(double)HALFLIFE_2);
calc_converged_max(y); //3493
break;
default: break;
}
}```

2. 测试结果

```/*
\$ ./pp 8 20
y^8=0.5, periods=20

util_sum=1024, periods=1, util_avg=%8
util_sum=1963, periods=2, util_avg=%15
util_sum=2824, periods=3, util_avg=%22
util_sum=3613, periods=4, util_avg=%29
util_sum=4337, periods=5, util_avg=%35
util_sum=5001, periods=6, util_avg=%40
util_sum=5610, periods=7, util_avg=%45
util_sum=6168, periods=8, util_avg=%50
util_sum=6680, periods=9, util_avg=%54
util_sum=7150, periods=10, util_avg=%57
util_sum=7581, periods=11, util_avg=%61
util_sum=7975, periods=12, util_avg=%64
util_sum=8337, periods=13, util_avg=%67
util_sum=8669, periods=14, util_avg=%70
util_sum=8974, periods=15, util_avg=%72
util_sum=9253, periods=16, util_avg=%75
util_sum=9509, periods=17, util_avg=%77
util_sum=9744, periods=18, util_avg=%78
util_sum=9959, periods=19, util_avg=%80
util_sum=10156, periods=20, util_avg=%82
*/```

二、测试递减

1. 测试程序

```#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define HALFLIFE_32 32
#define HALFLIFE_8 8
#define HALFLIFE_4 4
#define HALFLIFE_3 3
#define HALFLIFE_2 2

int util_avg_from_sudden_sleep_all_time(double y, int periods) {
int i;
double util_avg;
double util_sum = 0;

for (i = 0; i < periods; i++) {
util_avg = 1 * pow(y, i);
printf("periods=%d, util_avg=%%%d
", i+1, (int)(util_avg * 100));
}

return 0;
}

void main(int argc, char *argv[])
{
double y;
int choose = 32, periods = 200;

if (argc == 2) {
choose = atoi(argv[1]);
}

if (argc == 3) {
choose = atoi(argv[1]);
periods = atoi(argv[2]);
}

printf("y^%d=0.5, periods=%d

", choose, periods);

switch(choose) {
case 32:
y = pow(0.5, 1/(double)HALFLIFE_32);
util_avg_from_sudden_sleep_all_time(y, periods);
break;
case 8:
y = pow(0.5, 1/(double)HALFLIFE_8);
util_avg_from_sudden_sleep_all_time(y, periods);
break;
case 4:
y = pow(0.5, 1/(double)HALFLIFE_4);
util_avg_from_sudden_sleep_all_time(y, periods);
break;
case 3:
y = pow(0.5, 1/(double)HALFLIFE_3);
util_avg_from_sudden_sleep_all_time(y, periods);
break;
case 2:
y = pow(0.5, 1/(double)HALFLIFE_2);
util_avg_from_sudden_sleep_all_time(y, periods);
break;
default: break;
}
}```

2. 执行结果

```\$ ./pp 8 10
y^8=0.5, periods=10

periods=1, util_avg=%100
periods=2, util_avg=%91
periods=3, util_avg=%84
periods=4, util_avg=%77
periods=5, util_avg=%70
periods=6, util_avg=%64
periods=7, util_avg=%59
periods=8, util_avg=%54
periods=9, util_avg=%49
periods=10, util_avg=%45```

三、补充

1. 测试取 8 和 32，PELT 下连续慢跑 10 个周期 util_avg 的变化情况

```               y^8=0.5      y^32=0.5
y              0.917004043  0.978572062
y^10           0.420448208  0.805245166
1-y^10         0.579551792  0.194754834
1-y            0.082995957  0.021427938
(1-q^10)/(1-y) 6.982891875  9.088827624
util_avg       0.698289188  0.908882762```

y越大(指数N越小)，满跑的情况下，负载增加的越快。同理衰减的越慢，越利于性能越不利于功耗。

2. 满载增速：

```q = (1/2)^32
util_avg = (1-q^n)/(1-q) * 1024(1ms~=1024us) * 1024(scale)```

一直满载后一直休眠的util_avg的减速：

`util_avg = 1024(scale) * q^n`

• 相关阅读:
RecyclerView-------MainActivity代码
ListView控件
Java 内部类的阐述
JAVA匿名内部类
Process.Start(@"C:WindowsSystem32osk.exe") 找不到指定文件
The program can't start because AppVIsvSubsystems64.dll is missing from your computer
Rclone webapi 使用例子
C# lock 死锁问题排查方法
zeroc ICE 使用案例
log4net 纯代码配置
• 原文地址：https://www.cnblogs.com/hellokitty2/p/15361706.html