average load?表示系統在一段時間內的平均進程個數,也就是表示系統的繁忙程度。average load和CPU利用率不一樣,更加能夠表示系統的繁忙程度,下面將就係統的average load的計算和相關進行簡單介紹。
查看方法
在linux系統下使用uptime命令,或者查看/proc/loadavg都可以看到系統負載average load。使用uptime命令會顯示系統分別在過去的1分鐘,5分鐘和10分鐘裏的平均負載。
[root@localhost ~]# uptime
19:32:09 up 5 days, 8:53, 5 users, load average: 0.05, 0.04, 0.05
[root@localhost ~]# cat /proc/loadavg
0.04 0.04 0.05 1/394 23203
那麼uptime命令計算load average的工作原理是什麼呢?
計算方法
對於單cpu和多cpu情況,系統的average load情況稍有不同。單cpu是最簡單的情形,比如過去的平均一分鐘裏面,判斷系統處於運行或者等待狀態的進程數則表示系統的平均負載,但是在linux系統下稍有不同,那些處於io等待狀態的進程也會被納入去計算。這樣就導致CPU利用率可能和平均負載很不同,在大部分進程都在做IO的時候,即使平均負載很大,也會沒有很大的CPU利用率。另外,有些系統對於進程和線程的處理也很不一樣,有的對於每一個線程都會進行計算,有的只關注進程,對於超線程技術的線程來說,可能又是別的處理方式。對於多CPU的平均負載的計算,是在單CPU的情況下再除以CPU的個數。
文件: kernel/timer.c:
unsigned long avenrun[3];
static inline void calc_load(unsigned long ticks)
{
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;
count -= ticks;
if (count < 0) {
count += LOAD_FREQ;
active_tasks = count_active_tasks();
CALC_LOAD(avenrun[0], EXP_1, active_tasks);
CALC_LOAD(avenrun[1], EXP_5, active_tasks);
CALC_LOAD(avenrun[2], EXP_15, active_tasks);
}
}
內核中的函數sched.h
/*
* These are the constant used to fake the fixed-point load-average
* counting. Some notes:
* - 11 bit fractions expand to 22 bits by the multiplies: this gives
* a load-average precision of 10 bits integer + 11 bits fractional
* - if you want to count load-averages more often, you need more
* precision, or rounding will get you. With 2-second counting freq,
* the EXP_n values would be 1981, 2034 and 2043 if still using only
* 11 bit fractions.
*/
extern unsigned long avenrun[]; /* Load averages */
extern void get_avenrun(unsigned long *loads, unsigned long offset, int shift);
#define FSHIFT 11 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ+1) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */
#define CALC_LOAD(load,exp,n) \
load *= exp; \
load += n*(FIXED_1-exp); \
load >>= FSHIFT;
extern unsigned long total_forks;
extern int nr_threads;
DECLARE_PER_CPU(unsigned long, process_counts);
extern int nr_processes(void);
extern unsigned long nr_running(void);
extern unsigned long nr_uninterruptible(void);
extern unsigned long nr_iowait(void);
extern unsigned long nr_iowait_cpu(int cpu);
extern unsigned long this_cpu_load(void);
ewma算法
linux系統在很多方面都使用了這個算法,比如除了這個還有TC系統的CBQ算法,這是統計學的一個算法,具體請參考http://en.wikipedia.org/wiki/EWMA_chart和http://en.wikipedia.org/wiki/Moving_average
參考文獻
http://man.he.net/man8/tc-cbq-details
linux內核代碼
http://en.wikipedia.org/wiki/EWMA_chart
http://en.wikipedia.org/wiki/Moving_average