1. 程式人生 > >Linux效能優化-CPU使用率

Linux效能優化-CPU使用率

 

Linux作為一個多工作業系統,將每個CPU的時間劃分成很短的時間片,再通過排程器輪流分配給各個任務使用,因此造成了多個任務同時執行的錯覺
為了維護CPU時間,Linux通過實現定義的節拍率(核心中表示為HZ),觸發時間中斷,並使用全域性變數Jiffies記錄了開機以來的節拍數,每發生一次時間中斷,Jiffies的值就加1
節拍率HZ是核心的可配選項,可以設定為100,250,1000等,不同的系統可能設定不同數值,你可以通過查詢
/boot/config 核心選項來檢視他的配置值,
比如下面這個,就是每秒有1000個次的時間中斷

cat /boot/config-3.10.0-514.16.1.el7.x86_64 | grep HZ
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
# CONFIG_NO_HZ_IDLE is not set
CONFIG_NO_HZ_FULL=y
# CONFIG_NO_HZ_FULL_ALL is not set
CONFIG_NO_HZ=y
# CONFIG_RCU_FAST_NO_HZ is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
CONFIG_MACHZ_WDT=m

這個節拍率HZ是核心選項,所以使用者空間程式並不能直接訪問,為了方便使用者空間程式,核心還提供了一個使用者空間節拍率 USER_HZ,它總是固定為100,也就是1/100秒

 


Linux通過/proc 虛擬檔案系統,向用戶空間提供了系統內部狀態的資訊,而 /proc/stat 提供的就是系統的CPU和任務統計資訊,如果只關注CPU的話,可以執行下面命令

CPU      user%           nice%   system%  idle%              iowait%  irq%    softirq%  steal%  guest_nice%
cpu     46690956        1395    2756716 1100812644      62551   933     216878  35728   0
cpu0    11685110        348     676302  275161847       2032    179     80539   19513   0
cpu1    11655846        375     624830  275424074       1597    65      6651    2351    0
cpu2    11648679        337     680955  275312231       16027   222     36922   3776    0
cpu3    11701320        334     774627  274914491       42894   465     92765   10087   0

每一列的含義如下
1.user(縮寫us),表示使用者態CPU時間,不包括下面的nice時間,但包括了guest時間
2.nice(縮寫ni),表示低優先順序使用者態CPU時間,程序nice值為1-19之間的CPU時間,-20(最高)到19(最底)
3.sysem(sys),代表核心態CPU時間
4.idle(id)代表空閒時間,但不包括等待I/O的時間
5.iowait(wa),代表等待I/O的CPU時間
6.irq(hi),代表處理硬體中斷的CPU時間
7.softirq(si),代表處理軟中斷的CPU時間
8.steal(st),代表系統執行在虛擬機器中的時候,被其他虛擬機器佔用的CPU時間
9.guest(guest),代表通過虛擬化執行其他作業系統的時間,也就是執行虛擬機器的CPU時間
10.guest_nice(gnice),代表以低優先執行虛擬機器的時間

我們通常所說的CPU使用率,是除了空閒時間外的其他時間佔總CPU時間的百分比,用公式來表示為

根據這個公式,我們就可以從/proc/stat中的資料,計算出CPU使用率,
這個檔案中的值就是開機以來的節拍數累加值,直接算出來的,是開機以來的平均CPU使用率
為了計算CPU使用率,效能工具一般都會取間隔一段時間(如3秒)的兩次值,做差之後,再計算這段時間內的平均CPU使用率,公式如下

除了/proc/stat,還有/proc/[PID]/stat 這個檔案
這兩個檔案都會被各種系統性能分析工具讀取並解析,所以這兩個工具是系統指標的來源
效能分析工具給出的都是一段時間的平均CPU使用率,所以要注意間隔時間的設定,特別是用多個工具對比分析時,一定要保證他們用的是相同的間隔時間
比如top預設使用3秒時間間隔,而ps使用的是整個程序的生命週期
 

除了/proc/stat,還有/proc/[PID]/stat 這個檔案
這兩個檔案都會被各種系統性能分析工具讀取並解析,所以這兩個工具是系統指標的來源
效能分析工具給出的都是一段時間的平均CPU使用率,所以要注意間隔時間的設定,特別是用多個工具對比分析時,一定要保證他們用的是相同的間隔時間
比如top預設使用3秒時間間隔,而ps使用的是整個程序的生命週期


top顯示了系統總體的CPU和記憶體使用情況,以及各個程序的資源使用情況
ps 則只顯示了每個程序的資源使用情況
top的第三行就是CPU的各個指標的使用率情況
pidstat命令顯示每個程序的CPU使用率情況

 


GDB(The GUN Project Debugger),是一個程式除錯工具,在除錯程式錯誤方面很強大,但在除錯程式的過程中會中斷程式執行,在線上環境就不合適了,只適用於效能分析的後期,找到問題的大致函式後,線下再借助這個工具來進一步除錯函式內部的問題
perf比較適合在線上環境做效能分析,它以效能事件取樣為基礎,不僅可以分析系統的各種事件和核心效能,還可以用來分析指定營業程式的效能問題
比如perf top,類似top,能顯示佔用CPU始終最多的函式或指令,因此可以用來查詢熱點函式

Samples: 555  of event 'cpu-clock', Event count (approx.): 112367154                                                                                                    
Overhead  Shared Object            Symbol                                                                                                                               
   8.01%  [kernel]                 [k] vsnprintf
   4.28%  libc-2.17.so             [.] __strcmp_sse42
   3.75%  [kernel]                 [k] format_decode
   3.58%  [kernel]                 [k] __memcpy
   3.58%  [kernel]                 [k] kallsyms_expand_symbol.constprop.1
   3.07%  perf                     [.] 0x00000000000c53b4
   2.85%  [kernel]                 [k] _raw_spin_unlock_irqrestore
   2.73%  perf                     [.] __dso__load_kallsyms
   2.44%  perf                     [.] rb_next
   2.38%  perf                     [.] hex2u64
   2.10%  [kernel]                 [k] finish_task_switch
   1.87%  [kernel]                 [k] module_get_kallsym
   1.87%  [kernel]                 [k] number.isra.2
   1.70%  [kernel]                 [k] strnlen
   1.70%  libc-2.17.so             [.] _IO_getdelim
   1.70%  libc-2.17.so             [.] __memcpy_sse2
   1.57%  libc-2.17.so             [.] _int_malloc
   1.56%  libc-2.17.so             [.] __strchr_sse42
   1.54%  libc-2.17.so             [.] __memcpy_ssse3_back
   1.53%  perf                     [.] 0x00000000000c53c7
   1.42%  [kernel]                 [k] tick_nohz_idle_enter
   1.36%  [kernel]                 [k] string.isra.7
   1.27%  libpthread-2.17.so       [.] pthread_rwlock_unlock
   1.19%  [kernel]                 [k] pointer.isra.19
   1.07%  perf                     [.] rb_insert_color
   1.02%  libc-2.17.so             [.] __strlen_sse2_pminub
   0.86%  [kernel]                 [k] run_timer_softirq
   0.73%  libpthread-2.17.so       [.] pthread_rwlock_rdlock
   0.73%  perf                     [.] __symbols__insert
   0.71%  libc-2.17.so             [.] __memset_sse2
   0.68%  [kernel]                 [k] strlcpy
   0.68%  libc-2.17.so             [.] _IO_feof
   0.68%  libc-2.17.so             [.] memchr
   0.68%  libpthread-2.17.so       [.] pthread_mutex_init
   0.68%  perf                     [.] rb_erase
   0.67%  libc-2.17.so             [.] _int_free
   0.62%  libelf-0.168.so          [.] gelf_getsym
   0.62%  perf                     [.] symbols__insert
   0.61%  [kernel]                 [k] __do_softirq
   0.61%  [kernel]                 [k] rcu_gp_kthread
   0.56%  [kernel]                 [k] mem_cgroup_charge_common
   0.56%  perf                     [.] dso__load_sym
   0.51%  [kernel]                 [k] __x86_indirect_thunk_rax
   0.51%  [kernel]                 [k] clear_page_c_e

輸出結果中,第一行包含三個資料
分別是取樣數(Samples),時間型別(event)和事件總數量(Event count)
這裡的取樣了555個CPU時鐘事件,事件總數是112367154個,如果取樣數過少(只有十幾個)那麼排序和百分比意義就不大了
再往下看是一個表格樣式資料,每一行包含四列,分別是
1.Overhead, 是該符號的效能事件在所有采樣中的比例,用百分比來表示
2.Shared,   是該函式或指令所在的動態共享物件(Dynamic Shared Object)如核心,程序名,動態連結庫
  的名字,核心模組名字等
3.Object,   是動態共享物件的型別,比如[.]表示使用者空間的可執行程式,或動態連結庫,而[k]表示
   核心空間
4.Symbol,   是符號名,也就是函式名,當函式名未知時,用16進位制的地址來表示
perf工具本身也會佔用一定的CPU

perf top雖然實時展示了系統的效能資訊,但他的缺點是並不儲存資料,也就無法用於離線或後續分析,使用
perf record 儲存資料,perf report用於後續解析展示

 

 

參考

CONFIG_HZ 和 USER_HZ