マルチコア時代のロードアベレージの見方

ちょっと煽り気味のタイトルですが、CPU がマルチコアになり 2個、4個と増えていく中 Linux の負荷の指針になるロードアベレージをどう読むべきか、という話です。気になったところを少し調べたのでそのまとめを。

http://d.hatena.ne.jp/naoya/20070222/1172116665 でも書いたとおり、Linuxロードアベレージは「ロードアベレージは過去1分、5分、15分の間の実行待ちプロセス数の平均数 = 実行したくても他のプロセスが実行中で実行できないプロセスが平均で何個ぐらい存在してるか」を示す値です。ボトルネックが CPU、メモリ、ディスク等々どこにあるかは関係なく、仕事の実行までにどれぐらい待たされているかを示す値なので、システムのスループットを計測する指標の入り口になる値です。

このロードアベレージですが、実装を見るとランキュー(待ち行列)に溜まったタスク (task_struct構造体 ≒ プロセス)の数を、ハードウェアクロックの割り込み毎に数え上げて時間単位での平均値を出しているのがわかります。

ところでこのランキュー、Linux カーネル 2.6 の実装では CPU ごとに用意されています。CPU が一個のときは一つのランキューに溜まったタスクを数え上げるだけでよいところ、CPU が2個になるとロードアベレージの値はどうなるのでしょう。2コアが主流な昨今です。また、これから先 4 コア、8 コアと増えていった場合ロードアベレージが示す値はこれまでどおりの読みでよいのか、違う観点で見る必要があるのか、気になりますね。ということで実装を深追いします。カーネル 2.6.20 のコードから抜粋します。

まずは先のエントリーでも抜粋した kernel/timer.c。

static inline void calc_load(unsigned long ticks)
{
        unsigned long active_tasks; /* fixed-point */
        static int count = LOAD_FREQ;

        count -= ticks;
        if (unlikely(count < 0)) {
                active_tasks = count_active_tasks();
                do {
                        CALC_LOAD(avenrun[0], EXP_1, active_tasks);
                        CALC_LOAD(avenrun[1], EXP_5, active_tasks);
                        CALC_LOAD(avenrun[2], EXP_15, active_tasks);
                        count += LOAD_FREQ;
                } while (count < 0);
        }
}

static unsigned long count_active_tasks(void)
{
        return nr_active() * FIXED_1;
}

ここの calc_load() → count_active_tasks() がタイマー割り込み毎に呼び出されて CALC_LOAD マクロでロードアベレージが計算されているのでした。アクティブなタスクの数を求める nr_active() の実装は kernel/sched.c にあります。

unsigned long nr_active(void)
{
        unsigned long i, running = 0, uninterruptible = 0;

        for_each_online_cpu(i) {
                running += cpu_rq(i)->nr_running;
                uninterruptible += cpu_rq(i)->nr_uninterruptible;
        }

        if (unlikely((long)uninterruptible < 0))
                uninterruptible = 0;

        return running + uninterruptible;
}

この nr_active() の実装がポイントで、foreach_online_cpu で全CPUを舐めて、そのループ中で各 CPU に紐づいたキューの TASK_RUNNING と TASK_UNINTERUPPTIBLE なタスクを足しこんでいます。CPU が複数あるとランキューその同数になりますが、CPU ごとにアクティブタスク数を求めるのではなく、すべて合計しているのがここで分かります。

少し戻って、sched.c で使われているロードアベレージの計算マクロである CALC_LOAD を sched.h から。

extern unsigned long avenrun[];         /* Load averages */

#define FSHIFT          11              /* nr of bits of precision */
#define FIXED_1         (1<<FSHIFT)     /* 1.0 as fixed-point */
#define LOAD_FREQ       (5*HZ)          /* 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;

ここでは特に CPU の数に依存した演算は行っていません。

計算したロードアベレージの値は、カーネル内グローバルな配列である avenrun に保存されます。この avenrun に保存された値は

% cat /proc/loadavg
0.01 0.02 0.00 2/69 4279

と /proc ファイルシステムの /proc/loadavg から取得できます。top や sar、uptime などはここから値を読み取っています。実際、

% strace -e open uptime 2>&1 | grep loadavg
open("/proc/loadavg", O_RDONLY)         = 4

と trace を取るとはっきり分かります。この /proc/loadavg に値を出力している箇所を見てみます。/proc はファイルシステムなので実装コードは fs/proc 以下にあります。fs/proc/proc_misc.c の loadavg_read_proc() が該当箇所ですね。

static int loadavg_read_proc(char *page, char **start, off_t off,
                                 int count, int *eof, void *data)
{
        int a, b, c;
        int len;

        a = avenrun[0] + (FIXED_1/200);
        b = avenrun[1] + (FIXED_1/200);
        c = avenrun[2] + (FIXED_1/200);
        len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
                LOAD_INT(a), LOAD_FRAC(a),
                LOAD_INT(b), LOAD_FRAC(b),
                LOAD_INT(c), LOAD_FRAC(c),
                nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
        return proc_calc_metrics(page, start, off, count, eof, len);
}

と avenrun[] から 1分、5分、15分の値をそれぞれ取得して整形し出力しているのがわかります。と、ここまででロードアベレージのデータを取得して整形出力する一連の流れが分かりました。注目するのは、待ちタスク数を数え上げるのにすべてのキューを見て合計する一方、その後出力するまでに CPU の数でその値を割ったりはしていない、という点です。つまり、CPU の数が増えてもロードアベレージは CPU の数でタスク数を平均したりはせず、純粋に「待ち行列にたまって待たされたタスクの数」を示しているのがここではっきりします。

さて、一方CPU 使用率の方はどうでしょう。これはカーネルの実装を見る必要もなく top や sar の値は割り算をしているのがコマンド結果から分かります。例えば sar では sar -P ALL とすると、CPU が複数ある場合にそれぞれ別に表示することができます。以下はデュアルコアCPU x 2 = CPU 4 つのサーバーでの sar -P ALL です。

% sar -P ALL | head
Linux 2.6.19.2-4.hatena.centos44smp (kiratachi.hatena.ne.jp)    05/18/07

00:00:01          CPU     %user     %nice   %system   %iowait     %idle
00:10:01          all     22.70      0.00      3.29      0.01     74.00
00:10:01            0     49.14      0.00      2.85      0.01     48.00
00:10:01            1      7.04      0.00      1.11      0.01     91.84
00:10:01            2     16.63      0.00      6.31      0.01     77.05
00:10:01            3     17.97      0.00      2.91      0.00     79.12

all が示す CPU 使用率は 0 〜 3 番の CPU 使用率を足して割ったものであるのが見て取れます。sar や top は特にオプションなどを指定しない場合、CPU 数の数に関係ないシステム全体のCPU 使用率を示しますが、実際には各 CPU ごとに使用率(実際にはプロセスがそのCPUを使った時間)を取って保持しているのがここから分かります。(これらデータはカーネル内部で CPU 毎に用意された cpu_usage_stat 構造体のインスタンスに保持されています。)

なお、sar や top は /proc/stat から CPU 使用時間の情報を取得しています。

% cat /proc/stat | head -5
cpu  319538758 24136 11757832 1603696315 131407 489623 4303234 0
cpu0 190160191 2820 6287055 284134618 81551 489611 3829506 0
cpu1 21211171 5318 1591735 462090674 14624 4 71798 0
cpu2 40233011 6341 1806675 442794419 18733 4 126131 0
cpu3 67934384 9654 2072365 414676603 16498 4 275798 0

これらの数字から計算して %user %system 等各項目の数値を出している、という仕組みになっています。(proc_misc.c の show_stat() で整形して出力しています。)

ここで簡単にまとめておきます。

  • top や sar がデフォルトで示すCPU使用率はCPU数(コア数)で割り算をしている
  • ロードアベレージは割り算をしていない

というのが結論ですね。

ここからもう少しだけ深追いします。ロードアベレージは1未満に保っておければべスト、みたいなことが経験則として良く言われます。Google などで検索すると「CPU の数が増えた場合、その CPU の数で割った数未満を保っておけばよい。つまり 4つ CPU があるならロードアベレージは 4.00 まで OK」という話もちらほら。実際どうでしょう。ここまで見てきたように、ロードアベレージの値はすべてのランキューのタスク数を足しこんでいて CPU 使用率のようにCPU数で割り算をしているわけではないのでその話は一見正しいようにも思います。

が、ここに一つ罠があるような気がします。カーネルは本当にすべての CPU に均等にタスクを割り当てているかどうか、という点です。先のデュアルコア x 2 = 4CPU の sar をもっと見てみましょう。(このサーバーは prefork モデルで mod_perlウェブアプリケーションをサービスしているサーバーです。)

% sar -P 0 | head
Linux 2.6.19.2-4.hatena.centos44smp (kiratachi.hatena.ne.jp)    05/18/07

00:00:01          CPU     %user     %nice   %system   %iowait     %idle
00:10:01            0     49.14      0.00      2.85      0.01     48.00
00:20:02            0     47.53      0.00      2.49      0.00     49.98
00:30:01            0     43.69      0.00      2.28      0.01     54.03
00:40:01            0     41.48      0.00      2.37      0.01     56.14
00:50:01            0     40.74      0.00      2.44      0.01     56.80
01:00:01            0     39.31      0.00      2.20      0.02     58.48
01:10:01            0     39.65      0.00      2.22      0.01     58.12

% sar -P 1 | head
Linux 2.6.19.2-4.hatena.centos44smp (kiratachi.hatena.ne.jp)    05/18/07

00:00:01          CPU     %user     %nice   %system   %iowait     %idle
00:10:01            1      7.04      0.00      1.11      0.01     91.84
00:20:02            1      5.55      0.00      0.23      0.00     94.22
00:30:01            1      3.31      0.00      0.22      0.00     96.47
00:40:01            1      3.57      0.00      0.32      0.00     96.11
00:50:01            1      2.39      0.00      0.30      0.00     97.31
01:00:01            1      2.44      0.00      0.22      0.00     97.33
01:10:01            1      1.53      0.00      0.22      0.00     98.26

% sar -P 2 | head
Linux 2.6.19.2-4.hatena.centos44smp (kiratachi.hatena.ne.jp)    05/18/07

00:00:01          CPU     %user     %nice   %system   %iowait     %idle
00:10:01            2     16.63      0.00      6.31      0.01     77.05
00:20:02            2     10.85      0.00      0.27      0.00     88.88
00:30:01            2      7.91      0.00      0.38      0.00     91.70
00:40:01            2      7.12      0.00      0.27      0.00     92.60
00:50:01            2      7.51      0.00      0.40      0.00     92.08
01:00:01            2      5.48      0.00      0.36      0.00     94.15
01:10:01            2      5.33      0.00      0.21      0.01     94.45

% sar -P 3| head
Linux 2.6.19.2-4.hatena.centos44smp (kiratachi.hatena.ne.jp)    05/18/07

00:00:01          CPU     %user     %nice   %system   %iowait     %idle
00:10:01            3     17.97      0.00      2.91      0.00     79.12
00:20:02            3     17.63      0.00      0.49      0.01     81.86
00:30:01            3     14.97      0.00      1.09      0.00     83.94
00:40:01            3     13.80      0.00      0.43      0.00     85.76
00:50:01            3     14.11      0.00      0.49      0.00     85.40
01:00:01            3     13.09      0.00      0.41      0.00     86.50
01:10:01            3     11.07      0.00      0.35      0.00     88.58

負荷が全く均一になっていません。Linux カーネルは、L2 キャッシュやスレッドローカルバッファの効率を高めるために同じプロセスは同じ CPU にタスクを割り当てつつ、全体としては負荷が均等になるように極力がんばるというのがスケジューラの原則のようですが、あまり均等にはなっていないようです。

追記#3, #4 に追記しました。CPUロードバランスはランキューにタスクが溜まっている状態を条件に行われるので、上記のように負荷が低い場合はタスクが偏るようです。(複数のスレッドに)それなりに負荷がかかっている状況ではもっと分散されます。

ここから分かることは、4CPU ならロードアベレージ 4.00 まで OK というのは鵜呑みにはできなそう、ということです。CPU 負荷が偏っている結果、負荷の高い CPU のランキューは埋まっていて、そうでないものはスカスカという可能性がどうしても残ってしまいます。同じロードアベレージ 4.00 でも、

  • スケジューラの割り当てがうまくいかずにユーザーが4タスク待たされるのか
  • 各 CPU ごとに1つのタスクで1タスク待たされるのか

というのがロードアベレージの値だけでははっきりしません。各 CPU ごとのランキューを区別して統計を見れればその辺が分かるできるのですが、先に実装を見たようにロードアベレージは CPU 毎に保持する構造にはなっていないので、それは現時点では難しいのが分かります。

長くなってきました。まとめます。

  • top や sar がデフォルトで示すCPU使用率はCPU数(コア数)で割り算をしている。各CPUごとに値を保持している。
  • ロードアベレージは割り算をしていない。各CPU(ランキュー)ごとに値を保持するのではなく、システム全体で一つ。
  • 4CPU ならロードアベレージ 4.00 まで OK、は鵜呑みにしないほうがよさそう。状況によって異なるのでその他の指標も使って細かく統計を分析したほうがよい。
    • nr_running > 1 のときはロードバランスが適切に働く。そのため 4CPU なら 4.00 で割れ、というのは負荷があるときはそれなりに正しい。
  • ランキューに溜まってるタスク数が CPU 毎に見れたらいいのだけど、現時点のカーネルの実装では難しい。(全体のは sar -q で見れます。)

というのが分かりました。間違い、ツッコミそのほかありましたら是非コメント/トラックバック他にて教えていただけると嬉しいです。

追記

2007年05月19日 kazuhooku テストの仕方が悪いんじゃないか (両方 idle してるし)

とコメントをいただいたわけですが、テストというか実地で動いてるサーバーでの結果なんですよね。他にもいくつかの用途のサーバーで見てみましたが、傾向としてはだいたい一緒で特定の CPU に負荷が偏ることが多いようです。各種用途の sar の average 項を晒してみます。(なお、先のデータは prefork Apache 2.0 で mod_perl / カーネル 2.6.19 (自社でコンパイルしたもの) / CentOS 4.4 / Opteron 2212HE x 2 です。)

カーネル 2.6.19 (自社コンパイル) / CentOS 4.4 / Opteron 2212HE x2 / mysql 4.0.27 (NPTL)
00:00:01          CPU     %user     %nice   %system   %iowait     %idle
Average:          all      4.09      0.00      2.81      0.14     92.97
Average:            0     12.71      0.00      8.55      0.49     78.26
Average:            1      0.37      0.00      0.39      0.01     99.23
Average:            2      0.68      0.00      0.54      0.02     98.77
Average:            3      2.61      0.00      1.74      0.04     95.61

mysqld のスレッドは常時 30 本くらい。(thread_cache でキャッシュしてるのでそのぐらいになる) やはり CPU 0 に偏る。

カーネル 2.6.18 (CentOS 5標準) / CentOS 5 / Core 2 Duo E6600 / Apache 2.2 prefork mod_perl
00:00:01          CPU     %user     %nice   %system   %iowait     %idle
Average:          all     12.05      0.00      0.69      0.05      0.00     87.21
Average:            0     20.07      0.00      1.22      0.07      0.00     78.64
Average:            1      4.02      0.00      0.17      0.02      0.00     95.79

同じく。

カーネル 2.6.19 (自社コンパイル) / CentOS 4.4 / Opteron 2212HE x 2 / mysql 4.0.27 (NPTL)
00:00:01          CPU     %user     %nice   %system   %iowait     %idle
Average:          all      0.11      0.00      0.08      4.14     95.67
Average:            0      0.45      0.00      0.29     16.31     82.95
Average:            1      0.00      0.00      0.01      0.03     99.96
Average:            2      0.00      0.00      0.00      0.01     99.99
Average:            3      0.00      0.00      0.00      0.23     99.77

このホストは CPU ではなく I/O にボトルネックがありますが、iowait も特定 CPU に偏ってしまってます。

カーネル 2.6.19 (自社コンパイル) / CentOS 4.4 / Opteron 2212HE x 2 / Apache 2.2 worker
Average:          all      4.19      0.00      2.12      0.11     93.58
Average:            0     15.76      0.00      8.06      0.38     75.80
Average:            1      0.32      0.00      0.14      0.03     99.52
Average:            2      0.27      0.00      0.13      0.02     99.57
Average:            3      0.39      0.00      0.14      0.03     99.44

リバース proxy のホスト。ここも CPU 0 に偏り。

2.6.19 のコンパイルで CPU 周りは以下のような感じですね。

#
# Processor type and features
#
CONFIG_X86_PC=y
# CONFIG_X86_VSMP is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_L1_CACHE_BYTES=128
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_X86_INTERNODE_CACHE_BYTES=128
CONFIG_X86_TSC=y
CONFIG_X86_GOOD_APIC=y
CONFIG_MICROCODE=m
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
CONFIG_X86_HT=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_MTRR=y
CONFIG_SMP=y
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_BKL=y
# CONFIG_NUMA is not set
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_NR_CPUS=32
CONFIG_HOTPLUG_CPU=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_IOMMU=y
# CONFIG_CALGARY_IOMMU is not set
CONFIG_SWIOTLB=y
CONFIG_X86_MCE=y
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x200000
# CONFIG_SECCOMP is not set
# CONFIG_CC_STACKPROTECTOR is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_REORDER is not set
CONFIG_K8_NB=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ISA_DMA_API=y
CONFIG_GENERIC_PENDING_IRQ=y

Cent 4.4 の設定をベースにサーバー用途で CONFIG_PREEMPT_NONE を有効にしてあるぐらいですかね。Cent 5 では CONFIG_PREEMPT_VOLUNTARY ですが、データを見るにどちらにしても結果は大差ないのでスケジューラの負荷分散周りには関係なさそ。

追記#2

2007年05月19日 sasada linux あっれー、2.6のスケジューラってこうだっけ。記憶と違う。当然記憶の方が間違ってる。しかし、CPU毎のロードバランシングをKernelが監視していないとは、

監視してないってことはないですよ。sched.c を見ると

  • load_balance()
  • idle_balance()
  • pull_task()
  • move_tasks()
  • find_busiest_group()
  • find_busiest_queue()

等々、ロードバランシング用のコードとしてビジーな CPU やキュー、スレッドグループなんかを求めるための関数や特定のCPUから別のCPUのキューにタスクを移動する関数なんかがあって、schedule() などコアになる場所から定期的に呼ばれてます。ただ、この手の処理が色々ありすぎてどこがバランシングで支配的な処理なのかがよくわかりません。

追記#3

kazuhooku linux だと CPU 間の負荷調整を行うのは nr_running>1 の場合のみっぽい。naoya 氏のテストは負荷が軽すぎるんだと思う

おお、なるほど。load_balance() の

        if (busiest->nr_running > 1) {
                /*
                 * Attempt to move tasks. If find_busiest_group has found
                 * an imbalance but busiest->nr_running <= 1, the group is
                 * still unbalanced. nr_moved simply stays zero, so it is
                 * correctly treated as an imbalance.
                 */
                local_irq_save(flags);
                double_rq_lock(this_rq, busiest);
                nr_moved = move_tasks(this_rq, this_cpu, busiest,
                                      minus_1_or_zero(busiest->nr_running),
                                      imbalance, sd, idle, &all_pinned);
                double_rq_unlock(this_rq, busiest);
                local_irq_restore(flags);

                /* All tasks on this runqueue were pinned by CPU affinity */
                if (unlikely(all_pinned)) {
                        cpu_clear(cpu_of(busiest), cpus);
                        if (!cpus_empty(cpus))
                                goto redo;
                        goto out_balanced;
                }
        }

ここですね。ということは常時ロードアベレージが 1 を超えてるような時間帯で CPU 使用率が均一になってるかどうかを見ればよさそう。調べてみます。

追記#4

追記いっぱいですいません。Linux の CPU ロードバランスはランキューで待ちが発生しないと(nr_running > 1) 行われないということなので、負荷が高めのところで見てみます。

以下はとある MySQL サーバーでの sar -q。CPU は Optern 2212HE x 2 = 4コアです。

00:00:01      runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15
00:10:01            2       113      1.67      1.57      1.48
00:20:01            1       113      1.50      1.46      1.45
00:30:01            1       113      1.89      1.57      1.52
00:40:01            0       113      1.28      1.34      1.38
00:50:01            2       113      1.63      1.50      1.40
01:00:01            4       113      1.72      1.87      1.63
01:10:01            1       113      2.19      1.99      1.76

割と負荷がある。この時間帯の sar -u を見てみます。

00:00:01          CPU     %user     %nice   %system   %iowait     %idle
00:10:01          all     18.42      0.00     12.67      1.68     67.22
00:10:01            0     24.47      0.00     17.57      4.44     53.52
00:10:01            1     15.71      0.00     11.20      0.57     72.51
00:10:01            2     17.75      0.00     11.38      0.74     70.13
00:10:01            3     15.77      0.00     10.53      0.97     72.73
00:20:01          all     16.51      0.00     11.75      1.61     70.13
00:20:01            0     26.26      0.00     19.10      4.47     50.18
00:20:01            1     12.14      0.00      8.76      0.42     78.68
00:20:01            2     13.71      0.00     10.01      0.68     75.60
00:20:01            3     13.93      0.00      9.12      0.89     76.06
00:30:01          all     17.07      0.00     12.30      1.44     69.19
00:30:01            0     25.41      0.00     18.37      4.21     52.01
00:30:01            1     12.53      0.00      8.50      0.39     78.58
00:30:01            2     15.23      0.00     11.59      0.45     72.74
00:30:01            3     15.12      0.00     10.75      0.70     73.42
00:40:01          all     13.39      0.00      9.87      1.80     74.94
00:40:01            0     24.67      0.00     16.60      5.10     53.64
00:40:01            1      6.59      0.00      5.35      0.44     87.61
00:40:01            2     10.20      0.00      9.05      0.68     80.07
00:40:01            3     12.11      0.00      8.47      0.98     78.44
00:50:01          all     15.81      0.00     12.85      1.28     70.06
00:50:01            0     22.52      0.00     16.42      3.60     57.46
00:50:01            1     10.94      0.00     10.24      0.51     78.30
00:50:01            2     14.97      0.00     13.37      0.49     71.16
00:50:01            3     14.81      0.00     11.35      0.52     73.31
01:00:01          all     19.96      0.00     18.39      1.09     60.56
01:00:01            0     23.22      0.00     19.73      3.12     53.93
01:00:01            1     19.89      0.00     20.28      0.35     59.49
01:00:01            2     17.10      0.00     15.84      0.43     66.62
01:00:01            3     19.64      0.00     17.71      0.46     62.19
01:10:01          all     18.89      0.00     19.31      1.49     60.31
01:10:01            0     26.14      0.00     21.85      4.34     47.67
01:10:01            1     16.00      0.00     17.82      0.45     65.73
01:10:01            2     16.67      0.00     19.57      0.45     63.31
01:10:01            3     16.75      0.00     18.01      0.71     64.54

おお、CPU 0 番以外は割りと均一になってますね。となると(負荷があるとき && 均等に分散される場合は)「ロードアベレージは CPU で割れ」というのは正しい気もしますね。勉強になりました。多謝。

追記

この辺りの話をまとめて本に書きました。

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

よろしければご一読ください。