【Linux 性能优化】利用perf和CPU使用率定位异常函数
博主未授權任何人或組織機構轉載博主任何原創文章,感謝各位對原創的支持!
博主鏈接
文章目錄
- CPU 使用率
- 進程運行情況查詢
- 使用工具查看CPU使用率
- 定位導致CPU 使用率過高的函數
- perf top的使用
- perf record 和 perf report的使用
CPU 使用率
???????Linux 作為一個多任務操作系統,將每個 CPU 的時間劃分為很短的時間片,再通過調度器輪流分配給各個任務使用,因此造成多任務同時運行的錯覺。
???????為了維護 CPU 時間,Linux 通過事先定義的節拍率(內核中表示為 HZ),觸發時間中斷,并使用全局變量 Jiffies 記錄了開機以來的節拍數。每發生一次時間中斷,Jiffies 的值就加 1。
???????節拍率 HZ 是內核的可配選項,可以設置為 100、250、1000 等。不同的系統可能設置不同數值,你可以通過查詢 /boot/config 內核選項來查看它的配置值。比如在我的系統中,節拍率設置成了 250,也就是每秒鐘觸發 250 次時間中斷。
???????同時,正因為節拍率 HZ 是內核選項,所以用戶空間程序并不能直接訪問。為了方便用戶空間程序,內核還提供了一個用戶空間節拍率 USER_HZ,它總是固定為 100,也就是 1/100 秒。這樣,用戶空間程序并不需要關心內核中 HZ 被設置成了多少,因為它看到的總是固定值 USER_HZ。
???????Linux 通過 /proc 虛擬文件系統,向用戶空間提供了系統內部狀態的信息,而 /proc/stat 提供的就是系統的 CPU 和任務統計信息。比方說,如果你只關注 CPU 的話,可以執行下面的命令:
???????這里的輸出結果是一個表格。其中,第一列表示的是 CPU 編號,如 cpu0、cpu1 ,而第一行沒有編號的 cpu ,表示的是所有 CPU 的累加。其他列則表示不同場景下 CPU 的累加節拍數,它的單位是 USER_HZ,也就是 10 ms(1/100 秒),所以這其實就是不同場景下的 CPU 時間。
???????當然,這里每一列的順序并不需要你背下來。你只要記住,有需要的時候,查詢 man proc 就可以。不過,你要清楚 man proc 文檔里每一列的涵義,它們都是 CPU 使用率相關的重要指標,你還會在很多其他的性能工具中看到它們。下面,我來依次解讀一下:
- 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),代表以低優先級運行虛擬機的時間。
而我們通常所說的 CPU 使用率,就是除了空閑時間外的其他時間占總 CPU 時間的百分比,用公式來表示就是:
根據這個公式,我們就可以從 /proc/stat 中的數據,很容易地計算出 CPU 使用率。但是 /proc/stat 中的值是開機以來的節拍數累加值,所以直接算出來的,是開機以來的平均 CPU 使用率,一般沒啥參考價值。
事實上,為了計算 CPU 使用率,性能工具一般都會取間隔一段時間(比如 3 秒)的兩次值,作差后,再計算出這段時間內的平均 CPU 使用率,即:
進程運行情況查詢
???????Linux 也給每個進程提供了運行情況的統計信息,也就是 /proc/[pid]/stat。不過,這個文件包含的數據就比較豐富了,總共有 52 列的數據。我們這里就不贅述了,可以通過 man proc查閱具體含義。
使用工具查看CPU使用率
top pidstat 和 ps 是最常用的性能分析工具:
- top 顯示了系統總體的 CPU 和內存使用情況,以及各個進程的資源使用情況 。但是,top 并沒有細分進程的用戶態 CPU 和內核態 CPU;
- pidstat 一個專門分析每個進程 CPU 使用情況的工具,默認間隔 1 秒展示了進程的 5 組 CPU 使用率:
- 用戶態 CPU 使用率 (%usr);
- 內核態 CPU 使用率(%system);
- 運行虛擬機 CPU 使用率(%guest);
- 等待 CPU 使用率(%wait);
- 以及總的 CPU 使用率(%CPU);
- ps 則只顯示了每個進程的資源使用情況。
定位導致CPU 使用率過高的函數
???????perf 是 Linux 2.6.31 以后內置的性能分析工具。它以性能事件采樣為基礎,不僅可以分析系統的各種事件和內核性能,還可以用來分析指定應用程序的性能問題。
perf top的使用
???????perf top,類似于 top,它能夠實時顯示占用 CPU 時鐘最多的函數或者指令,因此可以用來查找熱點函數,使用界面如下所示:
輸出結果中,第一行包含三個數據,分別是采樣數(Samples)、事件類型(event)和事件總數量(Event count)。比如這個例子中,perf 總共采集了 610 個 CPU 時鐘事件,而總事件數則為 109736637。
另外,采樣數需要我們特別注意。如果采樣數過少(比如只有十幾個),那下面的排序和百分比就沒什么實際參考價值了。
再往下看是一個表格式樣的數據,每一行包含四列,分別是:
- 第一列 Overhead ,是該符號的性能事件在所有采樣中的比例,用百分比來表示;
- 第二列 Shared ,是該函數或指令所在的動態共享對象(Dynamic Shared Object),如內核、進程名、動態鏈接庫名、內核模塊名等;
- 第三列 Object ,是動態共享對象的類型。比如 [.] 表示用戶空間的可執行程序、或者動態鏈接庫,而 [k] 則表示內核空間;
- 最后一列 Symbol 是符號名,也就是函數名。當函數名未知時,用十六進制的地址來表示。
perf record 和 perf report的使用
???????perf top 雖然實時展示了系統的性能信息,但它的缺點是并不保存數據,也就無法用于離線或者后續的分析。而 perf record 則提供了保存數據的功能,保存后的數據,需要你用 perf report 解析展示。
關于perf report中的數據,怎么解讀我們會再寫一篇博文進行講解,感興趣的同學可以關注我的博客。
在實際使用中,我們還經常為 perf top 和 perf record 加上 -g 參數,開啟調用關系的采樣,方便我們根據調用鏈來分析性能問題。
???????性能分析工具給出的都是間隔一段時間的平均 CPU 使用率,所以要注意間隔時間的設置,特別是用多個工具對比分析時,你一定要保證它們用的是相同的間隔時間。
???????比如,對比一下 top 和 ps 這兩個工具報告的 CPU 使用率,默認的結果很可能不一樣,因為 top 默認使用 3 秒時間間隔,而 ps 使用的卻是進程的整個生命周期
這里是從善若水的博客,感謝您的閱讀???
總結
以上是生活随笔為你收集整理的【Linux 性能优化】利用perf和CPU使用率定位异常函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消息中间件之二:kafka详解
- 下一篇: 深入浅出 Docker