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算法,这是统计学的一个算法,具体请参考和
参考文献