Linux CPU 效能優化指南
本文主要幫助理解 CPU 相關的效能指標,常見的 CPU 效能問題以及解決方案梳理。
系統平均負載
簡介
系統平均負載:是處於可執行或不可中斷狀態的平均程式數。
可執行程式:使用 CPU 或等待使用 CPU 的程式
不可中斷狀態程式:正在等待某些 IO 訪問,一般是和硬體互動,不可被打斷(不可被打斷的原因是為了保護系統資料一致,防止資料讀取錯誤)
檢視系統平均負載
首先top
命令檢視程式執行狀態,如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND10760 user 20 0 3061604 84832 5956 S 82.4 0.6 126:47.61 Process29424 user 20 0 54060 2668 1360 R 17.6 0.0 0:00.03 **top**
程式狀態Status
程式可執行狀態為R
,不可中斷執行為D
(後續講解 top 時會詳細說明)
top檢視系統平均負載:
top - 13:09:42 up 888 days, 21:32, 8 users, load average: 19.95, 14.71, 14.01Tasks: 642 total, 2 running, 640 sleeping, 0 stopped, 0 zombie%Cpu0 : 37.5 us, 27.6 sy, 0.0 ni, 30.9 id, 0.0 wa, 0.0 hi, 3.6 si, 0.3 st%Cpu1 : 34.1 us, 31.5 sy, 0.0 ni, 34.1 id, 0.0 wa, 0.0 hi, 0.4 si, 0.0 st...KiB Mem : 14108016 total, 2919496 free, 6220236 used, 4968284 buff/cacheKiB Swap: 0 total, 0 free, 0 used. 6654506 avail Mem
這裡的load average
就表示系統最近 1 分鐘、5 分鐘、15 分鐘的系統瓶頸負載。
uptime檢視系統瓶頸負載
[root /home/user]# uptime 13:11:01 up 888 days, 21:33, 8 users, load average: 17.20, 14.85, 14.10
檢視 CPU 核資訊
系統平均負載和 CPU 核數密切相關,我們可以通過以下命令檢視當前機器 CPU 資訊:
lscpu檢視 CPU 資訊:
[root@Tencent-SNG /home/user_00]# lscpuArchitecture: x86_64CPU op-mode(s): 32-bit, 64-bitByte Order: Little EndianCPU(s): 8...L1d cache: 32KL1i cache: 32KL2 cache: 4096KNUMA node0 CPU(s): 0-7 // NUMA架構資訊
cat /proc/cpuinfo檢視每個 CPU 核的資訊:
processor : 7 // 核編號7vendor_id : GenuineIntelcpu family : 6model : 6...
系統平均負載升高的原因
一般來說,系統平均負載升高意味著 CPU 使用率上升。但是他們沒有必然聯絡,CPU 密集型計算任務較多一般系統平均負載會上升,但是如果 IO 密集型任務較多也會導致系統平均負載升高但是此時的 CPU 使用率不一定高,可能很低因為很多程式都處於不可中斷狀態,等待 CPU 排程也會升高系統平均負載。
所以假如我們系統平均負載很高,但是 CPU 使用率不是很高,則需要考慮是否系統遇到了 IO 瓶頸,應該優化 IO 讀寫速度。
所以系統是否遇到 CPU 瓶頸需要結合 CPU 使用率,系統瓶頸負載一起檢視(當然還有其他指標需要對比檢視,下面繼續講解)
案例問題排查
stress
是一個施加系統壓力和壓力測試系統的工具,我們可以使用stress
工具壓測試 CPU,以便方便我們定位和排查 CPU 問題。
yum install stress // 安裝stress工具
stress 命令使用
// --cpu 8:8個程式不停的執行sqrt()計算操作 // --io 4:4個程式不同的執行sync()io操作(刷盤) // --vm 2:2個程式不停的執行malloc()記憶體申請操作 // --vm-bytes 128M:限制1個執行malloc的程式申請記憶體大小 stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s
我們這裡主要驗證 CPU、IO、程式數過多的問題
CPU 問題排查
使用stress -c 1
模擬 CPU 高負載情況,然後使用如下命令觀察負載變化情況:
uptime:使用uptime
檢視此時系統負載:
# -d 參數列示高亮顯示變化的區域$ watch -d uptime... load average: 1.00, 0.75, 0.39
mpstat:使用mpstat -P ALL 1
則可以檢視每一秒的 CPU 每一核變化資訊,整體和top
類似,好處是可以把每一秒(自定義)的資料輸出方便觀察資料的變化,最終輸出平均資料:
13:14:53 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle13:14:58 all 12.89 0.00 0.18 0.00 0.00 0.03 0.00 0.00 0.00 86.9113:14:58 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0013:14:58 1 0.40 0.00 0.20 0.00 0.00 0.20 0.00 0.00 0.00 99.20
由以上輸出可以得出結論,當前系統負載升高,並且其中 1 個核跑滿主要在執行使用者態任務,此時大多數屬於業務工作。所以此時需要查哪個程式導致單核 CPU 跑滿:
pidstat:使用pidstat -u 1
則是每隔 1 秒輸出當前系統程式、CPU 資料:
13:18:00 UID PID %usr %system %guest %CPU CPU Command13:18:01 0 1 1.00 0.00 0.00 1.00 4 systemd13:18:01 0 3150617 100.00 0.00 0.00 100.00 0 stress...
top:當然最方便的還是使用top
命令檢視負載情況
top - 13:19:06 up 125 days, 20:01, 3 users, load average: 0.99, 0.63, 0.42
Tasks: 223 total, 2 running, 221 sleeping, 0 stopped, 0 zombie
%Cpu(s): 14.5 us, 0.3 sy, 0.0 ni, 85.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16166056 total, 3118532 free, 9550108 used, 3497416 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 6447640 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3150617 root 20 0 10384 120 0 R 100.0 0.0 4:36.89 stress
此時可以看到是stress
佔用了很高的 CPU。
IO 問題排查
我們使用stress -i 1
來模擬 IO 瓶頸問題,即死迴圈執行 sync 刷盤操作:uptime:使用uptime
檢視此時系統負載:
$ watch -d uptime..., load average: 1.06, 0.58, 0.37
mpstat:檢視此時 IO 消耗,但是實際上我們發現這裡 CPU 基本都消耗在了 sys 即系統消耗上。
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idleAverage: all 0.33 0.00 12.64 0.13 0.00 0.00 0.00 0.00 0.00 86.90Average: 0 0.00 0.00 99.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00Average: 1 0.00 0.00 0.33 0.00 0.00 0.00 0.00 0.00 0.00 99.67
IO 無法升高的問題:
iowait 無法升高的問題,是因為案例中 stress 使用的是 sync()
系統呼叫,它的作用是重新整理緩衝區記憶體到磁碟中。對於新安裝的虛擬機器,緩衝區可能比較小,無法產生大的 IO 壓力,這樣大部分就都是系統呼叫的消耗了。所以,你會看到只有系統 CPU 使用率升高。解決方法是使用 stress 的下一代 stress-ng,它支援更豐富的選項,比如stress-ng -i 1 --hdd 1 --timeout 600
(--hdd 表示讀寫臨時檔案)。
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idleAverage: all 0.25 0.00 0.44 26.22 0.00 0.00 0.00 0.00 0.00 73.09Average: 0 0.00 0.00 1.02 98.98 0.00 0.00 0.00 0.00 0.00 0.00
pidstat:同上(略)
可以看出 CPU 的 IO 升高導致系統平均負載升高。我們使用pidstat
查詢具體是哪個程式導致 IO 升高的。
top:這裡使用 top 依舊是最方面的檢視綜合引數,可以得出stress
是導致 IO 升高的元凶。
pidstat 沒有 iowait 選項:可能是 CentOS 預設的sysstat
太老導致,需要升級到 11.5.5 之後的版本才可用。
程式數過多問題排查
程式數過多這個問題比較特殊,如果系統執行了很多程式超出了 CPU 執行能,就會出現等待 CPU 的程式。使用stress -c 24
來模擬執行 24 個程式(我的 CPU 是 8 核)uptime:使用uptime
檢視此時系統負載:
$ watch -d uptime..., load average: 18.50, 7.13, 2.84
mpstat:同上(略)
pidstat:同上(略)
可以觀察到此時的系統處理嚴重過載的狀態,平均負載高達 18.50。
top:我們還可以使用top
命令檢視此時Running
狀態的程式數,這個數量很多就表示系統正在執行、等待執行的程式過多。
總結
通過以上問題現象及解決思路可以總結出:
平均負載高有可能是 CPU 密集型程式導致的 平均負載高並不一定代表 CPU 使用率高,還有可能是 I/O 更繁忙了 當發現負載高的時候,你可以使用 mpstat、pidstat 等工具,輔助分析負載的來源
總結工具:mpstat
、pidstat
、top
和uptime
CPU 上下文切換
CPU 上下文:CPU 執行每個任務都需要知道任務從哪裡載入、又從哪裡開始執行,也就是說,需要系統事先幫它設定好 CPU 暫存器和程式計數器(Program Counter,PC)包括 CPU 暫存器在內都被稱為 CPU 上下文。
CPU 上下文切換:CPU 上下文切換,就是先把前一個任務的 CPU 上下文(也就是 CPU 暫存器和程式計數器)儲存起來,然後載入新任務的上下文到這些暫存器和程式計數器,最後再跳轉到程式計數器所指的新位置,執行新任務。
CPU 上下文切換:分為程式上下文切換、執行緒上下文切換以及中斷上下文切換。
程式上下文切換
從使用者態切換到核心態需要通過系統呼叫來完成,這裡就會發生程式上下文切換(特權模式切換),當切換回使用者態同樣發生上下文切換。
一般每次上下文切換都需要幾十納秒到數微秒的 CPU 時間,如果切換較多還是很容易導致 CPU 時間的浪費在暫存器、核心棧以及虛擬記憶體等資源的儲存和恢復上,這裡同樣會導致系統平均負載升高。
Linux 為每個 CPU 維護一個就緒佇列,將 R 狀態程式按照優先順序和等待 CPU 時間排序,選擇最需要的 CPU 程式執行。這裡執行程式就涉及了程式上下文切換的時機:
程式時間片耗盡、。 程式在系統資源不足(記憶體不足)。 程式主動 sleep
。有優先順序更高的程式執行。 硬中斷髮生。
執行緒上下文切換
執行緒和程式:
當程式只有一個執行緒時,可以認為程式就等於執行緒。 當程式擁有多個執行緒時,這些執行緒會共享相同的虛擬記憶體和全域性變數等資源。這些資源在上下文切換時是不需要修改的。 執行緒也有自己的私有資料,比如棧和暫存器等,這些在上下文切換時也是需要儲存的。
所以執行緒上下文切換包括了 2 種情況:
不同程式的執行緒,這種情況等同於程式切換。 通程式的執行緒切換,只需要切換執行緒私有資料、暫存器等不共享資料。
中斷上下文切換
中斷處理會打斷程式的正常排程和執行,轉而呼叫中斷處理程式,響應裝置事件。而在打斷其他程式時,就需要將程式當前的狀態儲存下來,這樣在中斷結束後,程式仍然可以從原來的狀態恢復執行。
對同一個 CPU 來說,中斷處理比程式擁有更高的優先順序,所以中斷上下文切換並不會與程式上下文切換同時發生。由於中斷會打斷正常程式的排程和執行,所以大部分中斷處理程式都短小精悍,以便儘可能快的執行結束。
檢視系統上下文切換
vmstat:工具可以檢視系統的記憶體、CPU 上下文切換以及中斷次數:
// 每隔1秒輸出$ vmstat 1procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 3 0 0 157256 3241604 5144444 0 0 20 0 26503 33960 18 7 75 0 017 0 0 159984 3241708 5144452 0 0 12 0 29560 37696 15 10 75 0 0 6 0 0 162044 3241816 5144456 0 0 8 120 30683 38861 17 10 73 0 0
cs:則為每秒的上下文切換次數。
in:則為每秒的中斷次數。
r:就緒佇列長度,正在執行或等待 CPU 的程式。
b:不可中斷睡眠狀態的程式數,例如正在和硬體互動。
pidstat:使用pidstat -w
選項檢視具體程式的上下文切換次數:
$ pidstat -w -p 3217281 110:19:13 UID PID cswch/s nvcswch/s Command10:19:14 0 3217281 0.00 18.00 stress10:19:15 0 3217281 0.00 18.00 stress10:19:16 0 3217281 0.00 28.71 stress
其中cswch/s
和nvcswch/s
表示自願上下文切換和非自願上下文切換。
自願上下文切換:是指程式無法獲取所需資源,導致的上下文切換。比如說, I/O、記憶體等系統資源不足時,就會發生自願上下文切換。
非自願上下文切換:則是指程式由於時間片已到等原因,被系統強制排程,進而發生的上下文切換。比如說,大量程式都在爭搶 CPU 時,就容易發生非自願上下文切換
案例問題排查
這裡我們使用sysbench
工具模擬上下文切換問題。
先使用vmstat 1
檢視當前上下文切換資訊:
$ vmstat 1procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 0 514540 3364828 5323356 0 0 10 16 0 0 4 1 95 0 0 1 0 0 514316 3364932 5323408 0 0 8 0 27900 34809 17 10 73 0 0 1 0 0 507036 3365008 5323500 0 0 8 0 23750 30058 19 9 72 0 0
然後使用sysbench --threads=64 --max-time=300 threads run
模擬 64 個執行緒執行任務,此時我們再次vmstat 1
檢視上下文切換資訊:
$ vmstat 1procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 0 318792 3385728 5474272 0 0 10 16 0 0 4 1 95 0 0 1 0 0 307492 3385756 5474316 0 0 8 0 15710 20569 20 8 72 0 0 1 0 0 330032 3385824 5474376 0 0 8 16 21573 26844 19 9 72 0 0 2 0 0 321264 3385876 5474396 0 0 12 0 21218 26100 20 7 73 0 0 6 0 0 320172 3385932 5474440 0 0 12 0 19363 23969 19 8 73 0 014 0 0 323488 3385980 5474828 0 0 64 788 111647 3745536 24 61 15 0 014 0 0 323576 3386028 5474856 0 0 8 0 118383 4317546 25 64 11 0 016 0 0 315560 3386100 5475056 0 0 8 16 115253 4553099 22 68 9 0 0
我們可以明顯的觀察到:
當前 cs、in 此時劇增。 sy+us 的 CPU 佔用超過 90%。 r 就緒佇列長度達到 16 個超過了 CPU 核心數 8 個。
分析 cs 上下文切換問題
我們使用pidstat
檢視當前 CPU 資訊和具體的程式上下文切換資訊:
// -w表示檢視程式切換資訊,-u檢視CPU資訊,-t檢視執行緒切換資訊
$ pidstat -w -u -t 1
10:35:01 UID PID %usr %system %guest %CPU CPU Command
10:35:02 0 3383478 67.33 100.00 0.00 100.00 1 sysbench
10:35:01 UID PID cswch/s nvcswch/s Command
10:45:39 0 3509357 - 1.00 0.00 kworker/2:2
10:45:39 0 - 3509357 1.00 0.00 |__kworker/2:2
10:45:39 0 - 3509702 38478.00 45587.00 |__sysbench
10:45:39 0 - 3509703 39913.00 41565.00 |__sysbench
所以我們可以看到大量的sysbench
執行緒存在很多的上下文切換。
分析 in 中斷問題
我們可以檢視系統的watch -d cat /proc/softirqs
以及watch -d cat /proc/interrupts
來檢視系統的軟中斷和硬中斷(核心中斷)。我們這裡主要觀察/proc/interrupts
即可。
$ watch -d cat /proc/interruptsRES: 900997016 912023527 904378994 902594579 899800739 897500263 895024925 895452133 Rescheduling interrupts
這裡明顯看出重排程中斷(RES)增多,這個中斷表示喚醒空閒狀態 CPU 來排程新任務執行,
總結
自願上下文切換變多了,說明程式都在等待資源,有可能發生了 I/O 等其他問題。 非自願上下文切換變多了,說明程式都在被強制排程,也就是都在爭搶 CPU,說明 CPU 的確成了瓶頸。 中斷次數變多了,說明 CPU 被中斷處理程式佔用,還需要通過檢視 /proc/interrupts
檔案來分析具體的中斷型別。
CPU 使用率
除了系統負載、上下文切換資訊,最直觀的 CPU 問題指標就是 CPU 使用率資訊。Linux 通過/proc
虛擬檔案系統向使用者控制元件提供系統內部狀態資訊,其中/proc/stat
則是 CPU 和任務資訊統計。
$ cat /proc/stat | grep cpucpu 6392076667 1160 3371352191 52468445328 3266914 37086 36028236 20721765 0 0cpu0 889532957 175 493755012 6424323330 2180394 37079 17095455 3852990 0 0...
這裡每一列的含義如下:
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),代表以低優先順序執行虛擬機器的時間。
這裡我們可以使用top
、ps
、pidstat
等工具方便的查詢這些資料,可以很方便的看到 CPU 使用率很高的程式,這裡我們可以通過這些工具初步定為,但是具體的問題原因還需要其他方法繼續查詢。
這裡我們可以使用perf top
方便檢視熱點資料,也可以使用perf record
可以將當前資料儲存起來方便後續使用perf report
檢視。
CPU 使用率問題排查
這裡總結一下 CPU 使用率問題及排查思路:
使用者 CPU 和 Nice CPU 高,說明使用者態程式佔用了較多的 CPU,所以應該著重排查程式的效能問題。 系統 CPU 高,說明核心態佔用了較多的 CPU,所以應該著重排查核心執行緒或者系統呼叫的效能問題。 I/O 等待 CPU 高,說明等待 I/O 的時間比較長,所以應該著重排查系統儲存是不是出現了 I/O 問題。 軟中斷和硬中斷高,說明軟中斷或硬中斷的處理程式佔用了較多的 CPU,所以應該著重排查核心中的中斷服務程式。
CPU 問題排查套路
CPU 使用率
CPU 使用率主要包含以下幾個方面:
使用者 CPU 使用率,包括使用者態 CPU 使用率(user)和低優先順序使用者態 CPU 使用率(nice),表示 CPU 在使用者態執行的時間百分比。使用者 CPU 使用率高,通常說明有應用程式比較繁忙。 系統 CPU 使用率,表示 CPU 在核心態執行的時間百分比(不包括中斷)。系統 CPU 使用率高,說明核心比較繁忙。 等待 I/O 的 CPU 使用率,通常也稱為 iowait,表示等待 I/O 的時間百分比。iowait 高,通常說明系統與硬體裝置的 I/O 互動時間比較長。 軟中斷和硬中斷的 CPU 使用率,分別表示核心呼叫軟中斷處理程式、硬中斷處理程式的時間百分比。它們的使用率高,通常說明系統發生了大量的中斷。 除在虛擬化環境中會用到的竊取 CPU 使用率(steal)和客戶 CPU 使用率(guest),分別表示被其他虛擬機器佔用的 CPU 時間百分比,和執行客戶虛擬機器的 CPU 時間百分比。
平均負載
反應了系統的整體負載情況,可以檢視過去 1 分鐘、過去 5 分鐘和過去 15 分鐘的平均負載。
上下文切換
上下文切換主要關注 2 項指標:
無法獲取資源而導致的自願上下文切換。 被系統強制排程導致的非自願上下文切換。
CPU 快取命中率
CPU 的訪問速度遠大於記憶體訪問,這樣在 CPU 訪問記憶體時不可避免的要等待記憶體響應。為了協調 2 者的速度差距出現了 CPU 快取(多級快取)。如果 CPU 快取命中率越高則效能會更好,我們可以使用以下工具檢視 CPU 快取命中率,工具地址、專案地址 perf-tools
# ./cachestat -tCounting cache functions... Output every 1 seconds.TIME HITS MISSES DIRTIES RATIO BUFFERS_MB CACHE_MB08:28:57 415 0 0 100.0% 1 19108:28:58 411 0 0 100.0% 1 19108:28:59 362 97 0 78.9% 0 808:29:00 411 0 0 100.0% 0 908:29:01 775 20489 0 3.6% 0 8908:29:02 411 0 0 100.0% 0 8908:29:03 6069 0 0 100.0% 0 8908:29:04 15249 0 0 100.0% 0 8908:29:05 411 0 0 100.0% 0 8908:29:06 411 0 0 100.0% 0 8908:29:07 411 0 3 100.0% 0 89[...]
總結
通過效能指標查工具(CPU 相關)
效能指標 | 工具 | 說明 |
---|---|---|
平均負載 | uptime top | uptime 簡單展示最近一段時間的平均負載 top 展示更多指標 |
CPU 使用率 | vmstat mpstat top sar /proc/stat | top、vmstat、mpstat 只可以動態檢視當前,而 sar 可以檢視歷史 /proc/stat 是其他效能工具的資料來源 |
程式 CPU 使用率 | top pidstat ps htop atop | top、ps 可以以排序方式展示程式 CPU、pidstat 不可排序展示 htop、atop 則以不同顏色展示各類資料更直觀 |
系統上下文切換 | vmstat | 展示上下文切換此時、執行狀態、不可中斷狀態程式數量 |
程式上下文切換 | pidstat | 展示項很多,包括程式上下文切換資訊 |
軟中斷 | top /proc/softirqs mpstat | top 可檢視軟中斷 CPU 使用率 /proc/softirqs 和 mpstat 則可以檢視每個 CPU 上的累計資訊 |
硬中斷 | vmstat /proc/interrupts | vmstat 檢視總中斷次數資訊 /proc/interrupts 檢視各種中斷在每個 CPU 核心上的累計資訊 |
網路 | dstat sar tcpdump | dstat、sar 較詳細的展示出總的網路收發情況 tcpdump 提供動態抓取資料包的能力 |
IO | dstat、sar | 2 者都提供了詳細的 IO 整體情況 |
CPU 資訊 | /proc/cpuinfo lscpu | 都可以檢視 CPU 資訊 |
系統分析 | perf execsnoop | perf 分析各種核心函式呼叫、熱點函式資訊 execsnoop 監控短時程式 |
根據工具查效能指標(CPU 相關)
效能工具 | CPU 效能指標 |
---|---|
uptime | 5、10、15 分鐘內的平均負載展示 |
top | 平均負載、執行佇列、CPU 各項使用率、程式狀態和 CPU 使用率 |
htop | top 增強版,以不同顏色區分不同型別程式,展示更直觀 |
atop | CPU、記憶體、磁碟、網路資源全訪問監控,十分齊全 |
vmstat | 系統整體 CPU 使用率、上下文切換次數、中斷次數,還包括處於執行(r)和不可中斷狀態(b)的程式數量 |
pidstat | 程式、執行緒(-t)的每個 CPU 佔用資訊,中斷上下文切換次數 |
/proc/softirqs | 展示每個 CPU 上的軟中斷型別及次數 |
/proc/inerrupts | 展示每個 CPU 上的硬中斷型別及次數 |
ps | 每個程式的狀態和 CPU 使用率 |
pstree | 程式的父子關係展示 |
dstat | 系統整體 CPU 使用率(以及相關 IO、網路資訊) |
sar | 系統整體 CPU 使用率,以及使用率歷史資訊 |
strace | 跟蹤程式的系統呼叫 |
perf | CPU 效能事件分析,例如:函式呼叫鏈、CPU 快取命中率、CPU 排程等 |
execsnoop | 短時程式分析 |
CPU 問題排查方向
有了以上效能工具,在實際遇到問題時我們並不可能全部效能工具跑一遍,這樣效率也太低了,所以這裡可以先執行幾個常用的工具 top、vmstat、pidstat 分析系統大概的執行情況然後在具體定位原因。
top 系統CPU => vmstat 上下文切換次數 => pidstat 非自願上下文切換次數 => 各類程式分析工具(perf strace ps execsnoop pstack)
top 使用者CPU => pidstat 使用者CPU => 一般是CPU計算型任務
top 殭屍程式 => 各類程式分析工具(perf strace ps execsnoop pstack)
top 平均負載 => vmstat 執行狀態程式數 => pidstat 使用者CPU => 各類程式分析工具(perf strace ps execsnoop pstack)
top 等待IO CPU => vmstat 不可中斷狀態程式數 => IO分析工具(dstat、sar -d)
top 硬中斷 => vmstat 中斷次數 => 檢視具體中斷型別(/proc/interrupts)
top 軟中斷 => 檢視具體中斷型別(/proc/softirqs) => 網路分析工具(sar -n、tcpdump) 或者 SCHED(pidstat 非自願上下文切換)
CPU 問題優化方向
效能優化往往是多方面的,CPU、記憶體、網路等都是有關聯的,這裡暫且給出 CPU 優化的思路,以供參考。
程式優化
基本優化:程式邏輯的優化比如減少迴圈次數、減少記憶體分配,減少遞迴等等。 編譯器優化:開啟編譯器優化選項例如 gcc -O2
對程式程式碼優化。演算法優化:降低蘇研發複雜度,例如使用 nlogn
的排序演算法,使用logn
的查詢演算法等。非同步處理:例如把輪詢改為通知方式 多執行緒代替多程式:某些場景下多執行緒可以代替多程式,因為上下文切換成本較低 快取:包括多級快取的使用(略)加快資料訪問
系統優化
CPU 繫結:繫結到一個或多個 CPU 上,可以提高 CPU 快取命中率,減少跨 CPU 排程帶來的上下文切換問題 CPU 獨佔:跟 CPU 繫結類似,進一步將 CPU 分組,並通過 CPU 親和性機制為其分配程式。 優先順序調整:使用 nice 調整程式的優先順序,適當降低非核心應用的優先順序,增高核心應用的優先順序,可以確保核心應用得到優先處理。 為程式設定資源限制:使用 Linux cgroups 來設定程式的 CPU 使用上限,可以防止由於某個應用自身的問題,而耗盡系統資源。 NUMA 優化:支援 NUMA 的處理器會被劃分為多個 Node,每個 Node 有本地的記憶體空間,這樣 CPU 可以直接訪問本地空間記憶體。 中斷負載均衡:無論是軟中斷還是硬中斷,它們的中斷處理程式都可能會耗費大量的 CPU。開啟 irqbalance 服務或者配置 smp_affinity,就可以把中斷處理過程自動負載均衡到多個 CPU 上。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31509949/viewspace-2711585/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux 效能優化之 CPU 篇 ----- 套路篇Linux優化
- Linux 效能優化之 CPU 篇 ----- 殭屍程式Linux優化
- Linux 效能優化之 CPU 篇 ----- Linux 軟中斷Linux優化
- 前端效能優化指南前端優化
- MySQL效能優化指南MySql優化
- MongoDB效能優化指南MongoDB優化
- Linux 效能優化之 CPU 篇 ----- 上下文切換Linux優化
- Linux效能優化實戰CPU篇之總結(四)Linux優化
- Linux效能優化實戰CPU篇之軟中斷(三)Linux優化
- Vue 應用效能優化指南Vue優化
- PHP 應用效能優化指南PHP優化
- MySQL分頁效能優化指南MySql優化
- Angular應用效能優化指南Angular優化
- React 16 載入效能優化指南React優化
- Spark效能優化指南:高階篇Spark優化
- Spark效能優化指南:基礎篇Spark優化
- Linux 效能優化概述Linux優化
- Linux效能及調優指南:程式管理Linux
- 效能優化指南:效能優化的一般性原則與方法優化
- Vue 專案效能優化 — 實踐指南Vue優化
- MySQL資料庫的效能優化指南MySql資料庫優化
- Oracle效能優化求生指南讀後感Oracle優化
- Linux 效能優化筆記Linux優化筆記
- linux效能優化(轉帖)Linux優化
- 鄭建勳:Go程式效能分層優化 | CPU篇Go優化
- 一份平民化的MySQL效能優化指南MySql優化
- Python Django 效能測試與優化指南PythonDjango優化
- 移動H5前端效能優化指南H5前端優化
- 【前端效能優化】vue效能優化前端優化Vue
- Linux 效能優化之 IO 篇Linux優化
- Linux 效能優化之 cup 篇Linux優化
- Linux效能優化-平均負載Linux優化負載
- Linux效能優化實戰(一)Linux優化
- Linux效能優化實戰(二)Linux優化
- Oracle效能優化-資料庫CPU使用率100%Oracle優化資料庫
- RedHat 效能調優指南Redhat
- 「簡明效能優化」雙端開啟Gzip指南優化
- win10最大優化cpu設定_win10如何優化cpuWin10優化