web-dev-qa-db-ja.com

topコマンド-プロセスからのCPUは合計されません

topコマンドによって報告されるさまざまなタイプのCPU使用率(_6.5%us_、_17.2%sy_、_0.0%ni_など)を理解していますが、なぜ合計%CPUがプロセスごとに、Cpu(s)値のいずれにも加算されませんか?たとえば、以下のJavaプロセスは77.5%のCPUを消費していますが、Cpu(s)は76.0%がまだアイドル状態であることを示しています。これはなぜですか?これはシングルコアシステム上にあります。

_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   
_
3
OpenUserX03

比較している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はシステム全体の情報です[〜#〜] all [〜#〜] CPUとpidの個々のprocファイルはそれらの特定のpidのみの情報です。

したがって、それらは一致しません。

2

topがCPU使用率を測定する方法であるサンプリングは、エラーの対象となります。

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

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

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

6
David Schwartz