自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一文看得 Linux 性能分析

系統(tǒng) Linux
perf 工具的功能非常強大,但本文并不是介紹 perf 工具的使用,而是介紹 perf 的實現(xiàn)原理。介紹 perf 使用的文章多如牛毛,但介紹 perf 原理和實現(xiàn)的卻鳳毛麟角。

最近線上運行的程序出現(xiàn)性能問題,但通過分析程序源代碼(Code Review),并找不到導致問題的根本原因。所以,只能借助強大的性能分析工具 perf 來找出問題所在。

perf 工具的功能非常強大,但本文并不是介紹 perf 工具的使用,而是介紹 perf 的實現(xiàn)原理。介紹 perf 使用的文章多如牛毛,但介紹 perf 原理和實現(xiàn)的卻鳳毛麟角。

但正因為 perf 功能非常強大,所以其實現(xiàn)也是非常復雜的。本文只介紹其中的一個功能:分析進程中的函數調用頻率。

接下來,我們先介紹怎么使用 perf 來分析進程中的函數調用頻率。

使用 perf 分析程序性能瓶頸

在介紹 perf 的實現(xiàn)之前,我們先使用 perf 分析一個簡單的程序,此程序代碼如下:

// sample.c

void workload1()
{
int i, c = 0;

for (i = 0; i < 100000000; i++) {
c += i * i;
c -= i * 100;
c += i * i * i / 100;
}
}

void workload2()
{
int i, c = 0;

for (i = 0; i < 200000000; i++) {
c += i * i;
c -= i * 100;
c += i * i * i / 100;
}
}

int main(int argc, char *argv[])
{
workload1();
workload2();
return 0;
}

上面的程序很簡單,我們創(chuàng)建兩個函數:workload1? 和 workload2?。從代碼可以看出,workload2? 的負載是 workload1 的2倍。

現(xiàn)在我們使用 perf 來分析這個程序的性能瓶頸在哪里。

首先我們將程序編譯成可執(zhí)行文件,編譯時記得加上-g 參數,這樣 perf 才能獲取到函數名。

$ gcc sample.c -g -o sample

使用 perf 的record 命令來記錄程序的運行情況。

$ sudo perf record -g ./sample sleep 10

運行上面的命令后,將會生成一個 perf.data 的文件,此文件記錄了 sample 程序運行時的采樣數據。

使用 perf 的report 命令分析程序的運行情況。

$ perf report -g

結果如下圖所示:

圖片

從上圖可以看出,函數 workload2(65%)的負載大概是函數 workload1(35%)的 2 倍,與我們的代碼基本一致。

perf 實現(xiàn)原理

通過上面的例子,我們大概知道怎么使用 perf 來分析程序的性能瓶頸。接下來,我們將會介紹 perf 的內部實現(xiàn)原理。

來思考一下,如果讓我們來設計一個統(tǒng)計程序中各個函數占用 CPU 時間的方案,應該如何設計?最簡單的方案就是:在各個函數的開始記錄當前時間,然后在函數執(zhí)行結束后,使用當前時間減去函數開始執(zhí)行時的時間,得到函數的執(zhí)行時間總時長。如下偽代碼:

void func1()
{
...
}

void func2()
{
...
}

int main(int argc, char *argv[])
{
int start_time, total_time;

start_time = now();
func1();
total_time = now() - start_time;
printf("func1() spent %d\n", total_time);

start_time = now();
func2();
total_time = now() - start_time;
printf("func2() spent %d\n", total_time);
}

雖然上述方式可以統(tǒng)計程序中各個函數的耗時情況,但卻存在很多問題:

  • 代碼入侵度高。由于要對每個函數進行耗時記錄,所以必須在調用函數前和調用函數后加入統(tǒng)計代碼。
  • 統(tǒng)計函數耗時,并不能反映該函數的真實 CPU 使用率。比如函數內部調用了導致進程休眠的系統(tǒng)調用(如sleep),這時函數實際上是不使用CPU的,但函數的耗時卻統(tǒng)計了休眠的時間。
  • 對性能影響較大。由于程序中所有函數都加入統(tǒng)計代碼,所以對性能的影響是非常大的。

所以我們需要一個系統(tǒng),它能夠避免上述問題:

  • 零代碼入侵。
  • 能夠真實反映函數的 CPU 使用率。
  • 對性能影響較小。

perf 就是為了解決上述問題而生的,我們先來介紹一下 perf 的原理。

采樣

為了減小對程序性能的影響,perf 并不會在每個函數加入統(tǒng)計代碼,取而代之的統(tǒng)計方式是:采樣。

采樣的原理是:設置一個定時器,當定時器觸發(fā)時,查看當前進程正在執(zhí)行的函數,然后記錄下來。如下圖所示:

圖片

如上圖所示,每個 cpu-clock? 是一個定時器的觸發(fā)點。在 6 次定時器觸發(fā)點中,函數 func1? 被命中了 3 次,函數 func2? 被命中了 1 次,函數 func3 被命中了 2 次。所以,我們可以推測出,函數 func1 的 CPU 使用率最高。

排序

如果程序有成千上萬的函數,那么采樣出來的數據可能非常多,這個時候就需要對采樣的數據進行排序。

為了對采樣數據進行排序,perf 使用紅黑樹這種數據結構,如下圖所示:

圖片

如上圖所示,在 perf 采樣的數據中,有 7 個函數被統(tǒng)計了命中次數,perf 使用采樣到的數據構建一棵紅黑樹。

根據紅黑樹的特性,最右邊的節(jié)點就是被命中最多的函數,這樣就能把程序中 CPU 使用率最高的函數找出來。

總結

由于 perf 的功能非常強大,所以本文也只介紹了 perf 其中一種功能:統(tǒng)計函數的 CPU 使用率。

在下一篇文章中,我們將會介紹 perf 的代碼實現(xiàn)。Linux 的創(chuàng)始人 Linus 曾經說過:Read the f**king source code,要真正理解一個系統(tǒng),只能通過閱讀其源碼。

責任編輯:武曉燕 來源: Linux內核那些事
相關推薦

2019-03-18 11:15:07

Linux性能網絡

2022-08-01 14:59:57

Web前端后端

2019-07-01 09:22:15

Linux操作系統(tǒng)硬件

2020-09-03 06:35:44

Linux權限文件

2021-05-12 18:22:36

Linux 內存管理

2021-10-25 16:01:01

Linux設備樹字符串

2024-05-11 08:18:49

2023-12-29 15:30:41

內存存儲

2022-03-28 19:19:45

Linux時間子系統(tǒng)

2020-10-09 07:56:52

Linux

2023-12-15 15:55:24

Linux線程同步

2021-12-15 09:32:41

Linux系統(tǒng)負載

2021-10-06 20:23:08

Linux共享內存

2022-04-12 09:05:30

Linux時鐘

2021-12-08 22:29:41

經營分析體系

2024-10-10 17:55:57

LinuxACL訪問控制列表

2021-11-02 10:53:56

Linux機制CPU

2022-04-26 06:36:09

渠道分析數據采集

2022-05-12 13:44:35

數據分析數據

2020-12-18 11:54:22

Linux系統(tǒng)架構
點贊
收藏

51CTO技術棧公眾號