在Linux/Unix下,CPU利用率(CPU utilization)分為使用者態,系統態和空閑態,分別表示CPU處於使用者態執行的時間,系統核心執行的時間,和空閑系統進程執行的時間。平時所說的CPU利用率是指:CPU執行非系統空閑進程的時間 / CPU總的執行時間。(上述代碼中使用的方法為:1 - CPU空閑已耗用時間/總已耗用時間 ,與這個計算方法原理上是一樣的)
在Linux的核心中,有一個全域變數:Jiffies。 Jiffies代表時間。它的單位隨硬體平台的 不同而不同,系統裡定義了一個常數HZ----代表每秒種最小時間間隔的數目。這樣jiffies的單位就是1/HZ。Intel平台jiffies的單位是1/100秒,這就是系統所能分辨的最小時間間隔了。每個CPU時間片,Jiffies都要加1。 CPU的利用率就是用執行使用者態+系統態的Jiffies除以總的Jifffies來表示。
那麼,還有一個經常容易與CPU利用率(CPU utilization)混淆的詞 -- CPU負載(CPU load)。CPU負載取決於CPU隊列長度而不是CPU利用率,因為一個主機負載過重時,它的CPU利用率會接近100%,從而無法準確反應負載狀況,而使用CPU隊列長度則可以很直接反應CPU的負載量。比如說兩個系統,其中一個系統有3個進程在隊列中,而另一台有6個進程在隊列,如果使用CPU利用率表示負載水平,他們可能都是接近100%,而使用CPU隊列長度他們的負載量完全不同。
我們如何理解CPU負載。一隻單核的處理器可以形象得比喻成一條單車道。那麼: *** 0.00 表示目前橋面上沒有任何的車流。 實際上這種情況與 0.00 和 1.00 之間是相同的,總而言之很通暢,過往的車輛可以絲毫不用等待的通過。
*** 1.00 表示剛好是在這座橋的承受範圍內。 這種情況不算糟糕,只是車流會有些堵,不過這種情況可能會造成交通越來越慢。
*** 超過 1.00,那麼說明這座橋已經超出負荷,交通嚴重的擁堵。 那麼情況有多糟糕。 例如 2.00 的情況說明車流已經超出了橋所能承受的一倍,那麼將有多餘過橋一倍的車輛正在焦急的等待。3.00 的話情況就更不妙了,說明這座橋基本上已經快承受不了,還有超出橋負載兩倍多的車輛正在等待。
上面的情況和處理器的負載情況非常相似。一輛汽車的過橋時間就好比是處理器處理某線程 的實際時間。Unix 系統定義的進程運行時間長度為所有處理器核心的處理時間加上線程 在隊列中等待的時間。
和收過橋費的管理員一樣,你當然希望你的汽車(操作)不會被焦急的等待。所以,理想狀態 下,都希望負載平均值小於 1.00 。當然不排除部分峰值會超過 1.00,但長此以往保持這 個狀態,就說明會有問題,這時候你應該會很焦急。
在多處理器系統中,負載均值是基於核心的數量決定的。以 100% 負載計算,1.00 表示單個處理器,而 2.00 則說明有兩個雙處理器,那麼 4.00 就說明主機具有四個處理器。回到我們上面有關車輛過橋的比喻。1.00 我說過是「一條單車道的道路」。那麼在單車道 1.00 情況中,說明這橋樑已經被車塞滿了。而在雙處理器系統中,這意味著多出了一倍的 負載,也就是說還有 50% 的剩餘系統資源 ---- 因為還有另外條車道可以通行。
所以,單一處理器已經在負載的情況下,雙處理器的負載滿額的情況是 2.00,它還有一倍的資源可以利用。
實際上Linux系統中很多都是用CPU負載均值(load average)來代表當前系統的負載狀況,比如使用top命令:
[cpp] view plain copy long@long-Ubuntu:~$ top top - 20:12:45 up 3:05, 6 users, load average: 1.16, 1.27, 1.14 Tasks: 208 total, 1 running, 206 sleeping, 0 stopped, 1 zombie %Cpu(s): 11.8 us, 3.7 sy, 0.0 ni, 84.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 2067372 total, 1998832 used, 68540 free, 54104 buffers KiB Swap: 2095100 total, 25540 used, 2069560 free, 449612 cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6635 long 20 0 435m 79m 32m S 7.3 3.9 11:31.39 rhythmbox 4523 root 20 0 110m 61m 4804 S 5.3 3.0 8:34.14 Xorg 5316 long 9 -11 162m 5084 4088 S 4.3 0.2 6:01.53 pulseaudio 5793 long 20 0 114m 22m 13m S 4.3 1.1 0:23.38 gnome-terminal …… 在第一行的最後顯示的為 “ load average: 1.16 , 1.27 ,1.14”
使用“uptime”命令,效果也是類似:
[cpp] view plain copy long@long-Ubuntu:~$ uptime 20:15:01 up 3:07, 6 users, load average: 0.43, 0.97, 1.05 這三個數分別是:一分鐘內、五分鐘內、十五分鐘內的系統負載均值。也就是說,從右向左看這幾個資料,我們可以判斷系統負載的發展趨勢。 事實上,這正是CPU負載所需要測量的,因為負載均值不包括那些等待I/O、網路、資料或者其他不依賴CPU的進程或線程,它關注的僅僅是積極要求CPU時間的進程或線程。這與CPU利用率是有很大不同的。
負載均值與CPU利用率在兩個方面有很大的區別: 1) 負載均值用來估量CPU利用率的發展趨勢,而不是某一時刻的狀況 2) 負載均值包括所有CPU的需求,而不僅僅是在測量時活躍的
第三節 如何計算CPU利用率 在Linux系統中,可以用/proc/stat檔案來計算cpu的利用率(詳細可參考)。這個檔案包含了所有CPU活動的資訊,該檔案中的所有值都是從系統啟動開始累計到當前時刻。 如:
[cpp] view plain copy long@long-Ubuntu:~$ cat /proc/stat cpu 426215 701 115732 2023866 27329 4 557 0 0 0 cpu0 218177 117 57458 1013633 8620 0 6 0 0 0 cpu1 208038 584 58274 1010233 18709 4 550 0 0 0 intr 21217894 119 18974 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 146350 0 647836 370 86696 3 146156 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ctxt 38682044 btime 1362301653 processes 10118 procs_running 1 procs_blocked 0 softirq 11177991 0 6708342 2178 148765 86792 0 14537 1507468 29072 2680837
輸出解釋: (CPU 以及CPU0、CPU1、CPU2、CPU3每行的每個參數意思(以第一行為例))
參數 |
解釋 |
user (426215) |
從系統啟動開始累計到當前時刻,使用者態的CPU時間(單位:jiffies) ,不包含 nice值為負進程。1jiffies=0.01秒 |
nice (701) |
從系統啟動開始累計到當前時刻,nice值為負的進程所佔用的CPU時間(單位:jiffies) |
system (115732) |
從系統啟動開始累計到當前時刻,核心時間(單位:jiffies) |
idle (2023866) |
從系統啟動開始累計到當前時刻,除硬碟IO等待時間以外其它等待時間(單位:jiffies) |
iowait (27329) |
從系統啟動開始累計到當前時刻,硬碟IO等待時間(單位:jiffies) , |
irq (4) |
從系統啟動開始累計到當前時刻,硬停機時間(單位:jiffies) |
softirq (557) |
從系統啟動開始累計到當前時刻,非強制中斷時間(單位:jiffies) |