首先,top不计算负载平均值本身。它只是从/ proc / loadavg文件读取负载平均值(strace显示顶部打开/ proc / loadavg,然后定期读取)。 man proc对/ proc / loadavg说:
/proc/loadavg
The first three fields in this file are load average figures giving
the number of jobs in the run queue (state R) or waiting for disk I/O
(state D) averaged over 1, 5, and 15 minutes. They are the same as
the load average numbers given by uptime(1) and other programs. The
fourth field consists of two numbers separated by a slash (/). The
first of these is the number of currently executing kernel scheduling
entities (processes, threads); this will be less than or equal to the
number of CPUs. The value after the slash is the number of kernel
scheduling entities that currently exist on the system. The fifth
field is the PID of the process that was most recently created on
the system.
所以load average显示运行队列中的作业数。而您显示的是/ proc / loadavg中的前三个值。如果您运行cat / proc / loadavg,您将看到文件中的所有值。
顺便说一下,在第四个字段的描述中似乎有一个错误。我在C中编写了一个简单的测试程序,它从输入中读取一个整数N,然后创建N个线程,每个线程都运行一个不定式循环。当我运行我的程序并要求它创建256个线程。我只有8个处理器与HT。但是我在文件中看到这个:
>cat /proc/loadavg
74.44 21.04 10.59 259/931 17293
It is worth noting that the current explanation in proc(5) manual page
(as of man-pages version 3.21, March 2009) is wrong. It reports the
first number of the forth field as the number of currently executing
scheduling entities, and so predicts it can’t be greater than the
number of CPUs. That doesn’t match the real implementation, where this
value reports the current number of runnable threads
所以,回答你的问题:
If the load average is at 7, with 4 hyper-threaded processors, shouldn’t that means that the CPU is working to about 7/8 capacity?
不,这只是意味着您平均在作业队列中有7个运行的进程。
Why, then was it showing 50.0%id? How can it be idle half the time?
因为负载平均值并不意味着“CPU容量的百分比”。你的线程只是使用只有50%的CPU和50%的时间做别的事情。
最后下面是我的简单测试。建立使用g -pthread my_test.cpp -o my_test。运行./my_test 8,查看你的空闲时间,线程不断运行,不要花时间等待任何事情。或者运行./my_test 128查看负载平均值可能比CPU数量大得多。
#include
#include
#include
#include
#include
#include
#include
static void* __attribute__ ((noinline))
my_thread_func(void * arg)
{
printf("Thread %lld:\n", (long long)pthread_self());
volatile long long i = 0;
while (1) {
++i;
}
return 0;
}
int
main(int argc, char *argv[])
{
int num_threads;
pthread_t *my_threads;
num_threads = atoi(argv[1]);
my_threads = new pthread_t[num_threads];
for (int tnum = 0; tnum < num_threads; tnum++) {
pthread_create(&my_threads[tnum], NULL, &my_thread_func, NULL);
}
sleep (600);
return 0;
}