top コマンド - プロセスの CPU が加算されない

top コマンド - プロセスの CPU が加算されない

コマンドによって報告される CPU 使用率のさまざまなタイプtop( 6.5%us、、など) は理解していますが、各プロセスの合計 %CPU がいずれの値にも一致しないのはなぜでしょうか17.2%sy。たとえば、以下では、Java プロセスが 77.5% の CPU を消費していますが、76.0% はまだアイドル状態であると表示されています。これはなぜでしょうか。これはシングル コア システムの場合です。0.0%niCpu(s)Cpu(s)

top - 05:53:27 up 32 min,  2 users,  load average: 0.16, 0.29, 0.34
Tasks:  71 total,   1 running,  70 sleeping,   0 stopped,   0 zombie
Cpu(s):  6.5%us, 17.2%sy,  0.0%ni, 76.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:   1758616k total,   643432k used,  1115184k free,    12224k buffers
Swap:   917500k total,        0k used,   917500k free,   304608k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                                      
 1307 tomcat    20   0  683m 287m 9528 S 77.5 16.8  10:54.99 java                                                                                                                                                                          
 1571 ec2-user  20   0  2592 1096  872 R  1.0  0.1   0:08.61 top                                                                                                                                                                           
    1 root      20   0  2892 1364 1168 S  0.0  0.1   0:00.28 init                                                                                                                                                                          
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd            

編集: これはデュアル コア システムであることがわかりました。topコマンドが起動しているときに 1 を押した後の更新された出力は次のとおりです。

top - 06:10:21 up 49 min,  2 users,  load average: 0.28, 0.37, 0.34
Tasks:  71 total,   1 running,  70 sleeping,   0 stopped,   0 zombie
Cpu0  :  9.9%us, 19.7%sy,  0.0%ni, 69.0%id,  0.0%wa,  0.0%hi,  1.4%si,  0.0%st
Cpu1  :  5.0%us, 10.0%sy,  0.0%ni, 85.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1758616k total,   677548k used,  1081068k free,    13296k buffers
Swap:   917500k total,        0k used,   917500k free,   305732k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                                      
 1307 tomcat    20   0  683m 318m 9528 S 68.0 18.6  17:23.53 java                                                                                                                                                                          
    1 root      20   0  2892 1364 1168 S  0.0  0.1   0:00.28 init                                                                                                                                                                          
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd                                                                                                                                                                      
    3 root      20   0     0    0    0 S  0.0  0.0   0:00.91 ksoftirqd/0                                                                                                                                                                   
    4 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0   

答え1

比較する 2 つの情報は、異なるファイルから収集されているため、単純に一致しません。つまり、top は同じターミナルで情報を表示しますが、同じソースから収集されたわけではありません。

私は単に strace を上で実行しました (バッチ モードで実行)。これはシステム全体の CPU 情報を表示する場所です。

16:04:04.081092 open("/proc/stat", O_RDONLY) = 6 <0.000022>
16:04:04.081154 lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0 <0.000015>
16:04:04.081211 lstat("/proc/stat", {st_mode=S_IFREG|0444, st_size=0, ...}) = 0     <0.000013>
16:04:04.081267 fstat(6, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 <0.000013>
16:04:04.081334 fstat(6, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 <0.000013>
16:04:04.081385 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f699ace2000 <0.000016>
16:04:04.081440 lseek(6, 0, SEEK_SET)   = 0 <0.000013>
16:04:04.081494 read(6, "cpu  302573 6910 83103 10092403 "..., 1024) = 1024 <0.000070>
16:04:04.081656 write(1, "%Cpu(s):  2.9 us,  0.8 sy,  0.1 "..., 80) = 80 <0.000034>
16:04:04.081763 write(1, "KiB Mem:   8048484 total,  41402"..., 73) = 73 <0.000035>
16:04:04.081858 write(1, "KiB Swap:  8060924 total,       "..., 72) = 72 <0.000034>
16:04:04.081940 write(1, "\n", 1)       = 1 <0.000026>

ここで、 を見ると/proc/stat、システムのすべての CPU が表示されます。top もそれを認識しています。/proc/stat を開く前に、sys ファイルシステムを開くからです。

16:04:03.367339 open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3 <0.000027>
16:04:03.367408 read(3, "0-7\n", 8192)  = 4 <0.000019>
16:04:03.367464 close(3)                = 0 <0.000015>

さて、個々のプロセス情報を収集する場合は、ファイルから取得します/proc/pid/statm/proc/pid/stat(pid を実際の pid に置き換えます)。

ご覧のとおり、/proc/statシステム全体の情報です全てCPU と pid の個々の proc ファイルは、特定の pid のみの情報です。

つまり、一致しません。

答え2

topCPU 使用率を測定するサンプリングには誤差が生じる可能性があります。

これを説明する最も良い方法は、次のようになります。1 時間ごとに正確に 1 台の自動車を生産する工場を想像してください。工場の自動車生産速度をサンプリングすることにしたとします。5:59 にサンプリングを開始し、7:01 にサンプリングを終了します。6:00 に 1 台、7:00 に 1 台、合計 2 台の自動車が生産されたことがわかります。62 分間サンプリングし、2 台の自動車が生産されました。したがって、工場は定格容量の約 200% で自動車を生産していたと計算されます。

さらに、単一のシステム状態の測定値セットではなく、それぞれが独自の条件セットに従う独立した測定値セットが提供されるtopため、値を相互に比較することはできません。top

たとえば、CPU ごとの値は、プロセスごとの値とはまったく異なるメカニズムを使用して計算できます。CPU ごとの値は指数関数的に減少しますが、プロセスごとの値は 2 つの合計の差になります。つまり、まったく異なる方法論を使用して、同じ種類のものの測定値を反映できます。

関連情報