1. 程式人生 > >Linux效能優化從入門到實戰:04 基礎篇:CPU使用率

Linux效能優化從入門到實戰:04 基礎篇:CPU使用率

  CPU使用率是單位時間內CPU使用情況的統計,以百分比方式展示。

$ top
top - 11:46:45 up 7 days, 11:52,  1 user,  load average: 0.00, 0.01, 0.00
Tasks: 198 total,   1 running, 197 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.2 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4044232 total,   420136 free,  1061244 used,  2562852 buff/cache
KiB Swap:  1046524 total,  1043128 free,     3396 used.  2619124 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                        
  921 root      20   0  531332 138408  58972 S   0.7  3.4  41:31.24 Xorg                                                                           

  引數解析如下:

  • %user(us),代表使用者態 CPU 時間。不包括下面的 nice 時間,但包括了 guest 時間。
  • %nice(ni),代表低優先順序使用者態 CPU 時間,也就是程序的 nice 值被調整為 1-19 之間時的 CPU 時間。nice 可取值範圍是 -20 到 19,數值越大,優先順序反而越低。
  • %system(sys),代表核心態 CPU 時間。
  • %idle(id),代表空閒時間。不包括等待 I/O 的時間(iowait)。
  • %iowait(wa),代表等待 I/O 的 CPU 時間。
  • %irq(hi),代表處理硬中斷的 CPU 時間。
  • %softirq(si),代表處理軟中斷的 CPU 時間。
  • %steal(st),代表當系統執行在虛擬機器中的時候,被其他虛擬機器佔用的 CPU 時間。
  • %guest(guest),代表通過虛擬化執行其他作業系統的時間,也就是執行虛擬機器的 CPU 時間。
  • %guest_nice(gnice),代表以低優先順序執行虛擬機器的時間。
  • %CPU,每個程序的實時 CPU 使用率,是使用者態和核心態 CPU 使用率的總和。包括程序使用者空間使用的 CPU、通過系統呼叫執行的的核心空間 CPU 、以及在就緒佇列等待執行的 CPU。在虛擬化環境中,它還包括了執行虛擬機器佔用的 CPU。
      

檢視CPU使用的命令

  (1)top 預設使用 3 秒時間間隔,顯示了系統總體的 CPU 和記憶體使用情況,以及各個程序的資源總體使用情況。vmstat、mpstat 提高更詳細的分析多程序或者多執行緒應用。
  (2)ps 使用的卻是程序的整個生命週期,顯示了每個程序的資源使用情況。
  (3)pidstat 檢視每個程序的詳細CPU使用情況,包括使用者態和核心態CPU。

  

CPU使用率是通過CPU時間計數計算而來

  而我們通常所說的 CPU 使用率,就是除了空閒時間外的其他時間佔總 CPU 時間的百分比:
    在這裡插入圖片描述
  事實上,效能工具是取間隔時間作差,得到這段時間的平均CPU使用率:
    在這裡插入圖片描述
  同樣Linux也給每個程序統計資訊,/proc/[pid]/stat,通過上述方式計算使用率。
  為了維護 CPU 時間,Linux 通過事先定義的節拍率HZ,觸發時間中斷,並使用全域性變數 Jiffies 記錄了開機以來的節拍數。每發生一次時間中斷,Jiffies 的值就加 1。節拍率 HZ 是核心的可配選項,可以設定為 100、250、、1000 等。不同的系統可能設定不同數值,你可以通過查詢 /boot/config 核心選項來檢視它的配置值。$ grep ‘CONFIG_HZ=’ /boot/conf-$(uname -r)
  節拍率 HZ 是核心選項,使用者空間程式並不能直接訪問,為了方便使用者空間程式,核心還提供了一個使用者空間節拍率 USE_HZ,它總是固定為 100,也就是 1/100 秒。
  Linux 通過 /proc 虛擬檔案系統,向用戶空間提供系統內部狀態的資訊,而 /proc/stat 提供的就是系統的 CPU 和任務統計資訊,每一列則表示不同場景下 CPU 的累加節拍數,單位是 USER_HZ。
  

CPU使用率過高,如何進一步分析程序

  perf 以效能事件取樣為基礎,不僅可以分析系統的各種事件和核心效能,還可以用來分析指定應用程式的效能問題。
  (1)perf top,類似於 top,它能夠實時顯示佔用 CPU.時鐘最多的函式或者指令,中間不儲存資料,因此可以用來查詢熱點函式。若定位到的函式是十六進位制地址,說明沒有找到待分析程序所依賴的庫,解決方法是新增依賴庫,或用perf record後在有依賴的環境中檢視。

$ perf top
Samples: 175  of event 'cpu-clock', Event count (approx.): 43750000
Overhead  Shared Object            Symbol
   6.86%  perf                     [.] 0x00000000000a34ac
   5.71%  [kernel]                 [k] kallsyms_expand_symbol.constprop.1
   5.14%  [kernel]                 [k] format_decode

// 第一行 取樣數(Samples)、事件型別(event)和事件總數量(Event count)
//        採集了 175 個 cpu-clock 事件,而總事件數則為 43750000
//        取樣數過少,只有十幾個時,下面的排序和百分比沒有實際參考價值
// Overhead 是該符號的效能事件在所有采樣中的比例
// Shared 是該函式或指令所在的動態共享物件(Dynamic Shared Object),如核心、程序名、動態連結庫名、核心模組名等。
// Object 是動態共享物件的型別。比如 [.] 表示使用者空間的可執行程式、或者動態連結庫,而 [k] 則表示核心空間。
// Symbol 是符號名,也就是函式名。當函式名未知時,用十六進位制的地址來表示。

  (2)perf record 和 perf report,perf record 提供了儲存資料的功能,儲存後的資料,需要用 perf report 解析展示,用於離線或者後續的分析。

$ sudo perf record -g --all-cpus
// ^C 停止記錄,資料儲存在 perf.data 中,-g 開啟呼叫關係的取樣,--all-cpus 採集所有CPU事件
$ sudo perf report -g

  

CPU使用率過高的總體分析步驟

  Step1:通過 top、pidstat 找到哪個程序CPU使用率過高;
  Step2:通過 perf 找到該程序中具體哪個函式使用過高。$ perf top -g -p <pid_id>
  Step3:通過 grep 檢視該函式中的具體內容。$ grep -nr "<function_name>" <file_path>
  效能問題:
  (1)使用者 CPU 和 Nice CPU 高,說明使用者態程序佔用了較多的 CPU,所以應該著重排查程序的效能問題。
  (2)系統 CPU 高,說明核心態佔用了較多的 CPU,所以應該著重排查核心執行緒或者系統呼叫的效能問題。
  (3)I/O 等待 CPU 高,說明等待 I/O 的時間比較長,所以應該著重排查系統儲存是不是出現了 I/O 問題。
  (4)軟中斷和硬中斷高,說明軟中斷或硬中斷的處理程式佔用了較多的CPU,所以應該著重排查核心中的中斷服務程式。