CPU 利用率背後的真相,99% 人都搞錯了...


來源:內核月談
http://www.brendangregg.com/b...html

導讀:本文翻譯自 Brendan Gregg 去年的一篇博客文章 「CPU Utilization is Wrong」,從標題就能想到這篇文章將會引發爭議。

文章一上來就說,咱們「人人皆用、到處使用,每一個性能監控工具裏都在用」的 top 命令裏的 「%CPU」 指標,是不對的,其並不是用於衡量 CPU 的繁忙程度的正確指標,做者譴責了一下衆人(或許也包括你我)的這一行爲是具備很大的誤導性(deeply misleading)的,並且這種狀況還在連年惡化。對於這麼大一頂帽子,讓咱們暫且按下躁動的心,聽聽做者是怎麼深刻闡釋他的觀點的。segmentfault

1. 引言

可能你認爲的 90% CPU 利用率意味着這樣的情形:架構

而實際卻多是這樣的:less

CPU 並不是 90% 的時間都在忙着,很大一部分時間在等待,或者說「停頓(Stalled)」了。這種狀況表示處理器流水線停頓,通常由資源競爭、數據依賴等緣由形成。多數狀況下表現爲等待訪存操做,其中又以讀操做爲主。在停頓週期內,不能執行指令,這意味着你的程序不往前走。工具

值得注意的是,圖中 「Stalled」 狀態所佔的比例是做者依據生產環境中的典型場景計算而來,具備廣泛現實意義。所以,大多時候 CPU 處於停頓狀態,而你殊不知道,由於 CPU 利用率這個指標沒有告訴你真相。經過進一步分析 CPU 停頓的緣由,能夠指導代碼優化,提升執行效率,這是咱們深刻理解CPU微架構的動力之一。性能

2. CPU 利用率的真實含義是什麼?

咱們一般所說的CPU利用率是指 「non-idle time」:即CPU不執行 idle thread 的時間。操做系統內核會在上下文切換時記錄CPU的運行時間。優化

假設一個 non-idle thread 開始運行,100ms 後結束,內核會認爲這段時間內 CPU 利用率爲 100%。這種度量方式源於分時複用系統。早在阿波羅登月艙的導航計算機中,idle thread 當時被叫作 「DUMMY JOB」,工程師經過比對運行 「DUMMY JOB」 和 「實際任務」 的時間來衡量導航系統的利用率。spa

那麼這個所謂「利用率」的問題在哪兒呢?操作系統

當今時代,CPU 執行速度遠遠大於內存訪問速度,等待訪存的時間成爲佔用 CPU 時間的主要部分。當你在 top 中看到很高的 「%CPU」,你可能認爲處理器是瓶頸,但實際上倒是內存。線程

在過去很長一段時間內,CPU 頻率增加的速度大於 DRAM 訪存延時下降的速度(CPU DRAM gap),直到2005年先後,處理器廠商們纔開始放棄「頻率路線」,轉向多核、超線程技術,再加上多處理器架構,這些都致使訪存需求急劇上升。儘管廠商經過增大 cache 容量、優化 cache 策略、提高總線帶寬來試圖緩解訪存瓶頸,但咱們的程序仍深受 CPU stall 困擾。

3. 如何真正辨別 CPU 在作些什麼?

在 PMC(Performance Monitoring Counters) 的幫助下,咱們能看到更多的 CPU 運行狀態信息。下圖中,perf 採集了10秒內所有 CPU 的運行狀態。

這裏咱們重點關注的核心度量指標是 IPC(instructions per cycle),它表示平均每一個 CPU cycle 執行的指令數量,很顯然該數值越大性能越好。上圖中IPC 爲 0.78,看起來還不錯,是否是 78% busy 呢?現代處理器通常有多條流水線,運行 perf 的那臺機器,IPC 的理論值可達到 4.0。

若是咱們從 IPC的角度來看,這臺機器只運行到其處理器最高速度的 19.5%(0.78 / 4.0)。幸運的是,在處理器內部,有不少 PMU event,可用來幫助咱們分析形成 CPU stall 的緣由。用好 PMU 須要咱們熟悉處理器微架構,能夠參考 Intel SDM。

4. 最佳實踐是什麼?

若是 IPC < 1.0, 極可能是 Memory stall 佔主導,可從軟件和硬件兩個方面考慮這個問題。軟件方面:減小沒必要要的訪存操做,提高 cache 命中率,儘可能訪問本地節點內存;硬件方面:增長 cache 容量,加快訪存速度,提高總線帶寬。

若是IPC > 1.0, 極可能是計算密集型的程序。能夠試圖減小執行指令的數量:消除沒必要要的工做。火焰圖CPU flame graphs,很是適用於分析這類問題。硬件方面:嘗試超頻、使用更多的 core 或 hyperthread。做者根據PMU相關的工做經驗,設定了1.0這個閾值,用於區分訪存密集型(memory-bound)和計算密集型(cpu-bound)程序。讀者能夠根據本身的實際工做平臺,合理調整這個閾值。

5. 性能工具應該告訴咱們什麼?

做者認爲,性能工具中使用 %CPU 時都應該附帶上 IPC,或者將 %CPU 拆分爲指令執行消耗 cycle(%INS) 和 stalled 的 cycle(%STL)。對應到 top,在 Linux 系統有一個可以顯示每一個處理器 IPC 的工具 tiptop:

6. 其餘可能讓 CPU 利用率引發誤解的因素

除了訪存致使的 stall 容易讓人誤解 CPU 利用率外,還有其餘一些因素:

  • 溫度緣由致使處理器 stall;
  • Turboboost 干擾了時鐘速率;
  • 內核使得時鐘速率加快;
  • 平均帶來的問題:1分鐘利用率平均 80%,掩蓋了中間 100% 部分;
  • 自旋鎖: CPU 一直在被使用,同時 IPC 也很高,可是應用邏輯上並無任何進展。

7. 更新:CPU 利用率真的錯了嗎?

這篇文章引發了大量留言:

總結下做者的回答是:這裏討論的並非 iowait (那是磁盤IO),並且若是你已經確認是訪存密集型,是有些處理辦法(參考上面)。

那麼 CPU 利用率指標是確確實實錯誤的,仍是隻是容易誤導?如做者前面所說,他認爲許多人把高 CPU 利用率理解爲瓶頸在 CPU 上,這一行爲纔是錯誤的;

其實單看 CPU 利用率並不清楚瓶頸在何處,不少時候瓶頸是在外部。這個指標技術上看是否正確?若是 CPU stall 的週期並不能被其餘地方使用,它們是否是也就所以是「忙於等待「(聽起來有點矛盾)?在有些狀況,確實如此,你能夠說 CPU 利用率做爲操做系統級別的指標技術上看是對的,可是容易產生誤導。

從另外一個角度來講,有超線程的狀況下,那些 stalled 的週期是能夠被其餘線程使用的,這時 「%CPU」 可能會將可用的週期統計爲正在使用,這種狀況是錯誤的。這篇文章做者想關注的是解釋清楚這個問題,並給出解決方法建議,但沒錯,CPU 利用率這個指標自己也是存在一些問題的。

當你可能會說利用率做爲一個指標已經不對,Andrian Cockcroft以前討論已經指出過 (http://www.hpts.ws/papers/200..._HPTS-Useless.pdf )。

8. 結論

CPU 利用率已經開始成爲一個容易誤導的指標:它包含訪存致使的等待週期,這樣會影響一些新應用。也許 「%CPU」 應該重命名爲 「%CYC」(cycles的縮寫)。

要清楚知道 「%CPU」 的含義,須要使用其餘指標進行輔助,其中就包括每週期指令數(IPC)。IPC < 1.0 多半意味着訪存密集型,IPC > 1.0 多半意味着計算密集型。做者以前的文章中涵蓋有 IPC 說明,以及用於測量 IPC 的 Performance Monitoring Counters(PMCs)的介紹。

全部的性能監控產品若是展現 「%CPU」,都應該同時展現 PMC 指標用於解釋其真實意義,不要誤導用戶。好比,能夠把 「%CPU」 和 「IPC」 一塊兒放,或者說指令執行消耗週期和 stalled 週期。有這些指標以後,開發者和操做者就可以知道該如何更好地對應用和系統進行調優。

若有錯誤或其它問題,歡迎小夥伴留言評論、指正。若有幫助,歡迎點贊+轉發分享。

歡迎你們關注民工哥的公衆號:民工哥技術之路
image.png

相關文章
相關標籤/搜索