震驚,用了這麼多年的 CPU 利用率,其實是錯的

2021-02-07 人人都是極客

導讀:本文翻譯自 Brendan Gregg 去年的一片博客文章 「CPU Utilization is Wrong」,從標題就能想到這篇文章將會引起爭議。文章一上來就說,我們「人人皆用、處處使用,每個性能監控工具裡都在用」的 top 命令裡的 「%CPU」 指標,是不對的,其並非用于衡量 CPU 的繁忙程度的正確指標,作者譴責了一下眾人(或許也包括你我)的這一行為是具有很大的誤導性(deeply misleading)的,而且這種情況還在連年惡化。對於這麼大一頂帽子,讓我們暫且按下躁動的心,聽聽作者是怎麼深入闡釋他的觀點的。

1. 引言

可能你認為的 90% CPU 利用率意味著這樣的情形:

而實際卻可能是這樣的:

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」 和 「實際任務」 的時間來衡量導航系統的利用率。

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

當今時代,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 利用率真的錯了嗎?

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

http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html 的留言欄;

https://news.ycombinator.com/item?id=14301739

https://www.reddit.com/r/programming/comments/6a6v8g/cpu_utilization_is_wrong/

總結下作者的回答是:這裡討論的並不是 iowait (那是磁碟IO),而且如果你已經確認是訪存密集型,是有些處理辦法(參考上面)。

那麼 CPU 利用率指標是確確實實錯誤的,還是只是容易誤導?如作者前面所說,他認為許多人把高 CPU 利用率理解為瓶頸在 CPU 上,這一行為才是錯誤的;其實單看 CPU 利用率並不清楚瓶頸在何處,很多時候瓶頸是在外部。這個指標技術上看是否正確?如果 CPU stall 的周期並不能被其他地方使用,它們是不是也就因此是「忙於等待「(聽起來有點矛盾)?在有些情況,確實如此,你可以說 CPU 利用率作為作業系統級別的指標技術上看是對的,但是容易產生誤導。從另一個角度來說,有超線程的情況下,那些 stalled 的周期是可以被其他線程使用的,這時 「%CPU」 可能會將可用的周期統計為正在使用,這種情況是錯誤的。這篇文章作者想關注的是解釋清楚這個問題,並給出解決方法建議,但沒錯,CPU 利用率這個指標本身也是存在一些問題的。

當你可能會說利用率作為一個指標已經不對,Andrian Cockcroft之前討論已經指出過 (http://www.hpts.ws/papers/2007/Cockcroft_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 周期。有這些指標之後,開發者和操作者就能夠知道該如何更好地對應用和系統進行調優。

【文章摘自內核月談】


添加極客助手微信,加入技術交流群

長按,掃碼,關注公眾號


相關焦點

  • CPU 利用率背後的真相,只有 1% 人知道
    文章一上來就說,我們「人人皆用、處處使用,每個性能監控工具裡都在用」的 top 命令裡的 「%CPU」 指標,是不對的,其並非用于衡量 CPU 的繁忙程度的正確指標,作者譴責了一下眾人(或許也包括你我)的這一行為是具有很大的誤導性(deeply misleading)的,而且這種情況還在連年惡化。對於這麼大一頂帽子,讓我們暫且按下躁動的心,聽聽作者是怎麼深入闡釋他的觀點的。
  • Linux CPU負載與利用率
    如果是多核多cpu,比如現在是2個cpu,每個cpu是1個核,那麼理論上總負載不能超過2。2、如何查看CPU信息?(1)查看單個cpu核數:cat /proc/cpuinfo | grep "cpu cores"|uniq(2)查看物理CPU個數:cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l(3)查看邏輯CPU的個數:cat
  • CPU多少錢的好 應該買哪個?每日一答
    CPU這個東西算是一個非常厲害的產品了,這麼多年過來竟然都沒有被盜版,也是得益於此,它的售價一直就非常穩定,定位相近的處理器產品這麼多年以來一直售價也相差不是很大,隨著消費能力的提升,反而好多人都覺得越來越便宜了(當然我是對比手機來說的)。
  • 指甲其實是要成方的?剪了這麼多年指甲,你可能都用錯了方法!
    我迅速用自己作為醫生的儲備知識幫助他解決了問題,之後聊起給孩子剪指甲的問題,才發現我這朋友關於「剪指甲」的誤區是一大片!不僅這麼多年自己沒剪對,給孩子也剪得都是錯的!想著可能很多新手爸媽也會有相似的情況,今天專門寫一篇關於剪指甲、給孩子剪指甲的科普。因為剪了這麼多年指甲,你可能剪得「都是假的」!
  • 這麼多年「捲尺」你都用錯了!
    那麼它到底是做什麼用呢?下面這張圖會讓你瞬間理解~沒錯,它就是可以這樣卡在釘子上,然後就不用另外一隻手,或者另外一個人幫你固定捲尺了。其實在使用捲尺測量物體的外徑的話,你需要將捲尺向後拉,這樣測量的結果就是準確的。如果你測量物體的內徑的話,捲尺尺鉤本身就有厚度,這時候你就需要將這段可移動的距離縮回去。
  • 看過才知道這麼多年用錯了
    看過才知道這麼多年用錯了!不知道從哪天開始,在民間就流傳著這樣一種說法,味精不能多吃,吃了是有毒的。以前的我們是把味精作為主要調味料的,無論做什麼飯菜,只要放了鹽之後一定會放味精的,但是自從有了這種說法之後,我們就不放味精了。而且那段時間之後就流行起了雞精,雞精完全可以說是趁人之危,趁著人們對味精有所誤解,一夜之間就崛起了。
  • cpu-z怎麼用,cpu-z使用教程
    很多人知道cpu-z,可能更多的是通過它來了解電腦的顯存大小,不過除了查看顯存這樣的功能,對了解我們電腦配置情況也是有著極大的參考作用的,下面我來說下cpu-z怎麼用,cpu-z使用教程。安裝好cpu-z後,在我們桌面雙擊打開cpu-z的運行圖標。
  • 實測手機8核CPU有沒有用
    發展多年的PC平臺上尚且如此,在安卓上,8核CPU真的能夠物盡其用嗎?很多用戶都調侃8核安卓機經常出現「1核有難,7核圍觀」的情況,這是真的嗎?今天,筆者就來為大家測試一下,現在的安卓系統和安卓App,對8核CPU的利用率到底如何!
  • 老奶奶都能看懂的CPU技術科普
    但是我沒有在國內學習過cpu架構,所以有些名字我的確不喜歡或者不知道中文翻譯,會用英語原文。儘量不用這種文縐縐的語氣,多點用調侃或者比較非正式的話語。2. 在這邊的公司面試的時候,我遇到過一個比較有趣的問題是:你要設計cpu,你怎麼向你奶奶解釋你現在的工作。首先,我奶奶已經去世了,也沒辦法向她解釋。其實,這是一個非常有趣的問題,為什麼面試的時候回經常問?
  • 洗臉,究竟應該用熱水涼水還是溫水?這麼多年你用錯了嗎?
    也許這麼多年以來你洗臉的方式都是錯的,至於為什麼是錯誤的呢?今天小編就來跟你說一說,首先要問你一個問題,洗臉究竟是應該用熱水涼水還是溫水呢,你平常日子裡面洗臉用的是哪種溫度的水呢?這麼多年來你是否用錯了。今天我們就來一探究竟吧。小編今天就教大家一個洗臉的小竅門,同時告訴大家正確的洗臉水溫,讓大家能夠恢復童顏哦。
  • 運動鞋最後一個小孔原來是這樣用的,系錯了這麼多年
    其實這是因為你的鞋帶系錯啦!鞋舌亂擺、鞋子不跟腳,其實都是因為運動鞋上最後兩個小孔! 最後用平時繫鞋帶的方法繫上,鞋帶就系好了。▽ 用這個方法系上之後,腳背的地方會和鞋面緊緊相貼,可以讓鞋子更加的跟腳,不容易鬆動,也不會磨出水泡。▽
  • 這麼多年我們都錯了,真相其實是這樣!
    這麼多年我們都錯了,真相其實是這樣!對我們牙齒不好的人來說,從小肯定是會聽說過一個名叫蟲牙的詞語的,而且如果不注意的話,肯定會使自己的牙齒變成蟲牙的。那麼有蟲牙的人真的是牙齒裡會有蟲子嗎?有些人也是被這個問題困擾了很長時間的,其實答案並不是我們想像的這樣,他也是有一些原因而引起的,只是我們生活中沒有注意到這些細節而已。
  • 電腦開機黑屏顯示CPU Fan Error,這麼做有用!
    經過排查,發現是cpu風扇電源插錯了。那么正確的CPU風扇電源應該怎麼插呢?話不多說,直接上圖。大家看到了嗎,CPU風扇應該插在圖中標記的這個位置,而且圖中的主板上有明顯的標記「CPU FAN」的字樣,所以正確的插法應該是插在這個位置。為了大家能夠更好,更清楚的看到這個風扇電源的位置,把圖放大一點。
  • 看完才明白,原來這麼多年想錯了
    看完才明白,原來這麼多年想錯了對於公雞是如何讓母雞孵小雞的?相信很多人都沒見過吧!現在基本上很多人都在城市裡面生活,對於這個問題其實不是很了解,而且很多人知道就算沒有公雞,母雞也能下蛋,公雞好像沒什麼用,其實公雞用處也很大,農村人都知道,要是家裡沒有公雞,母親是孵化不出小雞的,那麼今天我們就來說一下公雞是如何讓母雞孵小雞的?看完才明白,原來這麼多年想錯了。
  • 馬桶上的衝水按鈕,這麼多年用錯了,每個月花了不少冤枉錢
    馬桶上的衝水按鈕,這麼多年用錯了,每個月花了不少冤枉錢嗨嘍大家好,馬桶是大家每天都要使用很多次的,用完之後大家要做的就是按下按鈕衝水,用這個方法來保持馬桶的衛生和潔淨,之前就有朋友說,這個馬桶的按鈕設計的不合理,就是一個衝水按鈕
  • 吃了這麼多年巧克力,才知道上面的凹槽有啥用,原來一直想錯了
    巧克力一直是我們大家都比較喜歡的一個零食,巧克力的味道吃起來香城好吃,除了小快巧克力之外還有一些大塊巧克力,上面有很多凹曹,其實大家在看到巧克力上的這些凹槽的時候,都會覺得這個凹槽一定是讓我們在吃巧克力的時候方便把巧克力掰開食用,其實這樣的想法是錯誤的。
  • 喝了這麼多年的小米粥,才發現在自己熬粥的方式是錯的!
    上次去朋友家,朋友在做小米粥,還讓我也嘗了嘗,沒想到小米粥這樣做出來味道這麼好喝,於是我就向朋友要了做法,朋友也就把她的做法告訴了我,回家我也試著做了一下,朋友說的那個方法確實好用,做出來的小米粥就是不一樣,原來我喝了這麼多年的小米粥,才發現在自己熬粥的方式是錯的!
  • Android CPU性能測試
    原理CPU的問題一般分為以下三類:1、CPU資源冗餘使用:關於這個問題的原因,可能是算法太爛,明明可以只遍歷一次卻遍歷了兩次,主要出現在查找、排序、刪除等環節;也可能是沒有用緩存,明明解碼過一次的圖片還重複解碼;還有就是明明使用int就足夠,偏偏要用long,導致CPU的運算壓力多出4倍。
  • 你還認為玩DNF很卡是顯卡和CPU的問題嗎?可能你想錯了方向!
    Hello各位勇士大家好,最近有很多粉絲向我留言,問自己的電腦玩DNF很卡是怎麼回事,是不是顯卡或者cpu太爛了。然而我看了很多人的電腦配置後,發現他們的cpu和顯卡其實是完全足夠流暢運行DNF的,那麼到底是什麼原因呢?我今天就以自己的親身經歷來給各位分析一下。
  • cpu高不是問題?如果不是,那什麼才是問題?
    cpu如何計算當我們執行top命令的時候,看到裡面的值(主要是cpu和load)值是一直在變的,因此有必要簡單了解一下Linux系統中cpu的計算方式。cpu分為系統cpu和進程、線程cpu,系統cpu的統計值位於/proc/stat下(以下的截圖未截全):