Linux性能優化實戰CPU篇之總結(四)

一、分析CPU瓶頸

1,性能指標

a>CPU使用率

  CPU使用率描述了非空閒時間佔總CPU時間的百分比,根據CPU上運行任務的不同可以分爲:用戶CPU、系統CPU、等待I/O 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時間百分比

b>平均負載

  系統的平均活躍進程數。它反應了系統的整體負載情況,主要包括三個數值,分別指過去1分鐘、過去5分鐘和過去15分鐘的平均負載。

  理想情況下,平均負載等於邏輯CPU個數,這表示每個CPU都恰好被充分利用。如果平均負載大於邏輯CPU個數,就表示負載比較重。

c>上下文切換

  • 無法獲取資源而導致的自願上下文切換
  • 被系統強制調度導致的非自願上下文切換

  上下文切換,本身是保證Linux正常運行的一項核心功能。但過多的上下文切換,會將原本運行進程的CPU時間,消耗寄存器、內核棧以及虛擬內存等數據的保存和恢復上,縮短進程真正運行的時間,成爲性能瓶頸。

d>CPU的緩存命中率

  https://cloud.tencent.com/developer/article/1597149

  CPU的處理速度要比內存的訪問速度快很多,CPU在訪問內存的時候,就需要等待內存的響應。爲了協調二者的巨大性能差距,CPU緩存(多級緩存)就出現了

   

   CPU緩存的速度介於CPU和內存之間,緩存的是熱點的內存數據。根據不斷增長的熱點數據,這些緩存按照大小不同分爲L1、L2、L3等三級緩存,其中L1和L2常用在單核中,L3則用在多核中。

  從L1到L3,三級緩存的大小依次增大,相應的性能依次降低(當然比內存好很多)。而它們的命中率,衡量的是CPU緩存的複用情況,命中率越高,則表示性能越好。

2,性能工具

a>平均負載

  uptime查看系統的平均負載。在平均負載升高時,使用mpstat和pidstat,分別觀察每個CPU和每個進程CPU的使用情況,進而定位負載升高的進程

b>上下文切換

  vmstat查看系統的上下文切換次數和中斷次數。使用pidstat (-w),觀察進程的自願上下文切換(cswch/s)和非自願上下文切換(nvcswch/s);使用pidstat(-wt)輸出具體線程的上下文切換。

c>CPU使用率升高

  使用top觀察具體的CPU情況,然後使用perf工具定位具體的線程和函數

d>不可中斷進程和殭屍進程

  top觀察iowait升高,並發現出現大量的zombie殭屍進程,使用dstat定位爲磁盤讀取導致,再使用pidstat找出相關進程,最後用perf工具定位原因

e>軟中斷

  top觀察cpu使用率升高,再使用watch -d /proc/softirqs,找到變化速率較快的軟中斷,然後通過sar(-n DEV)顯示網絡收發的報告,發現爲網絡小包問題,最後用tcpdump,找到網絡幀的類型和來源,確定爲SYNFLOOD攻擊導致。

3,性能指標和性能工具關聯

a>根據指標找工具

   

b>根據工具查指標

   

 c>分析CPU性能瓶頸

  

二、CPU性能優化的思路

1,如何評估性能優化效果

a>確定性能的量化指標

  不要侷限在單一維度的指標上。以web項目爲例:

  • 應用程序的維度,可以用吞吐量和請求延遲來評估應用程序的性能
  • 系統資源的維度,可以用CPU使用率來評估系統的CPU使用情況

b>測試優化前的性能指標

c>測試優化後的性能指標

2,CPU優化

a>應用程序優化

  降低CPU使用率的最好方法是排除所有不必要的工作,只保留最核心的邏輯。比如減少循環的層次、減少遞歸、減少動態內存分配等。

  除此之外,應用程序的優化也包括很多方法,最常用的:

  • 編譯器優化:很多編譯器都會提供優化選項,適當開啓。比如,gcc就提供了優化選項 -O2,開啓後會自動對應用程序的代碼進行優化。
  • 算法優化:使用複雜度更低的算法,可以顯著加快處理速度。比如,在數據比較大的情況下,可以用O(nlogn)的排序算法(如快排、歸併排序等),代替O(n^2)的排序算法(如冒泡、插入排序等)。
  • 異步處理:使用異步處理,可以避免程序因爲等待某個資源而一直阻塞,從而提升程序的併發處理能力。比如,把輪詢替換爲事件通知,就可以避免輪詢耗費CPU的問題。
  • 多線程代替多進程:相對於進程上下文切換, 線程上下文切換並不切換進程選址空間,因此可以降低上下文切換的成本
  • 善用緩存:經常訪問的數據或者計算過程中的步驟,可以放到內存中緩存起來,這樣在下次用時就能直接從內存中獲取,加快程序的處理速度。

b>系統優化

  從系統的角度來說,優化CPU的運行,一方面要充分利用CPU緩存的本地性,加速緩存訪問;另一方面,就是要控制進程的CPU使用情況,減少進程間的相互影響。常見方法:

  • CPU綁定:把進程綁定到一個或者多個CPU上,可以提高CPU緩存的命中率,減少跨CPU調度帶來的上下文切換問題
  • CPU獨佔:跟CPU綁定類似,進一步將CPU分組,並通過CPU親和性機制爲其分配進程。這樣,這些CPU就由指定的進程獨佔,換句話說,不允許其他進程再來使用這些CPU。
  • 優先級調整:使用nice調整進程的優先級,正值調低優先級,負值調高優先級。適當降低非核心應用的優先級,增高核心應用的優先級,可以確保核心應用得到優先處理。
  • 爲進程設置資源限制:使用Linux cgroups 來設置進程的CPU使用上限,可以防止由於某個應用自身的問題,而耗盡系統資源
  • NUMA(Non-Uniform Memory Accesss)優化:支持NUMA的處理器會被劃分爲多個node,每個node都有自己的本地內存空間。NUMA優化,其實就是讓CPU儘可能只訪問本地內存。
  • 中斷負載均衡:無論軟中斷還是硬中斷,它們的中斷處理程序都可能會耗費大量的CPU。開啓irqbalance服務或者配置smp_affinity,就可以吧中斷處理過程自動負載均衡到多個CPU上。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章