1. 程式人生 > 其它 >排程器3——PELT演算法下util_avg的增速和減速

排程器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 LOAD_AVG_MAX_32 47742

#define
HALFLIFE_8 8 #define LOAD_AVG_MAX_8 12326 #define HALFLIFE_4 4 #define LOAD_AVG_MAX_4 6430 #define HALFLIFE_3 3 #define LOAD_AVG_MAX_3 4959 #define HALFLIFE_2 2 #define LOAD_AVG_MAX_2 3493 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--; printf("#define LOAD_AVG_MAX %ld\n
", max); printf("#define LOAD_AVG_MAX_N %d\n\n", 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); util_avg = util_sum / load_avg_max; printf("util_sum=%d, periods=%d, util_avg=%%%d\n", (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\n", choose, periods); switch(choose) { case 32: y = pow(0.5, 1/(double)HALFLIFE_32); calc_converged_max(y); //47742 util_avg_from_sudden_running_all_time(y, periods, LOAD_AVG_MAX_32); break; case 8: y = pow(0.5, 1/(double)HALFLIFE_8); calc_converged_max(y); //12326 util_avg_from_sudden_running_all_time(y, periods, LOAD_AVG_MAX_8); break; case 4: y = pow(0.5, 1/(double)HALFLIFE_4); calc_converged_max(y); //6430 util_avg_from_sudden_running_all_time(y, periods, LOAD_AVG_MAX_4); break; case 3: y = pow(0.5, 1/(double)HALFLIFE_3); calc_converged_max(y); //4959 util_avg_from_sudden_running_all_time(y, periods, LOAD_AVG_MAX_3); break; case 2: y = pow(0.5, 1/(double)HALFLIFE_2); calc_converged_max(y); //3493 util_avg_from_sudden_running_all_time(y, periods, LOAD_AVG_MAX_2); break; default: break; } }

2. 測試結果

/*
$ ./pp 8 20
y^8=0.5, periods=20
#define LOAD_AVG_MAX 12326
#define LOAD_AVG_MAX_N 85

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\n", 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\n\n", 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