OProfile 是一個低管理費用的系統全局的性能監視工具。它使用處理器上的性能監視硬件來檢索關於內核以及系統上的可執行文件的信息,例如內存是何時被引用的;L2 緩存請求數量;收到的硬件中斷數量等。在紅帽企業 Linux 系統上,你必須安裝 oprofile RPM 軟件包才能使用該工具。
許多處理器都包含專用的性能監視硬件。該硬件能夠在某些事件發生時(如所請求的數據不在緩存內)檢測到它們。硬件通常是一個或多個計數器(counters),它們在每次事件發生時都遞增一位。當計數器的值“翻轉還原”,中斷就會生成,從而能夠控制性能監視的詳細程度(以及由此帶來的費用)。
OProfile 使用這個硬件(若沒有性能監視硬件則使用一個基於計時器的代用品)來在每次計數器生成中斷時收集與性能相關的數據樣品(samples)。這些樣品被定期寫入磁盤;稍後,其中的數據就會被用來生成系統級別和應用程序級別的性能報告。
OProfile 是一個很有用的工具,但是請了解使用它的一些局限性:
-
對共享庫的使用 — 除非使用 --separate=library 選項,共享庫中的編碼樣品不會成為某個特定應用程序的屬性。
-
性能監視樣品不精確 — 當性能監視註冊器引發了抽樣行動,中斷處理將不會明確給出例外的類型。由於處理器要無序地執行指令,樣品可能會在附近的指令上被抽取。
-
oprofpp 不能夠正確地歸類內聯函數樣品 — oprofpp 使用一個簡單的地址範圍機制來決定它所在的是哪個函數的地址。內聯函數樣品不從屬於那個內聯函數,而是從屬於那個內聯函數所插入的函數。
-
OProfile 從多次運行中積累數據 — OProfile 是一個系統範圍內的建檔器,它預計進程會被多次啟動和關閉。這樣,樣品就會從多次運行實例中被積累下來。使用 opcontrol
--reset 來清除從以前運行實例中抽取的樣品。
-
非 CPU 約束的性能問題 — OProfile 能夠找出受 CPU 約束的進程的問題。OProfile 不會識別正處於睡眠狀態的進程,因為這些進程正在等待鎖或其它事件的發生(如等待 I/O 設備完成操作)。
在Redhat Enterprise Linux 中,只有多處理器(SMP)內核才啟用了 OProfile 支持。要判定運行的是哪個內核,使用以下命令:
如果返回的內核版本以 .entsmp 結束,運行的就是多處理器內核。否則,即使系統不是多處理器系統,也請通過紅帽網絡或發行光盤來安裝它。多處理器內核可以在單處理器內核上運行。
第1節 工具總覽
表1提供了對 oprofile 軟件包中包括的工具的總覽。
命令 |
描述 |
opcontrol |
配置要收集的數據。詳情請參閱第2 節。
|
op_help |
顯示系統處理器的可用事件以及每個事件的簡單描述。
|
op_merge |
合並同一可執行文件的多個樣品。詳情請參閱第5.4 節。
|
op_time |
提供對所有建檔的可執行文件的總覽。詳情請參閱第5.1
節。 |
op_to_source |
如果應用程序使用調試符號編譯了,創建帶註解的源碼。詳情請參閱第5.3
節。 |
oprofiled |
作為守護進程來運行,定期把樣品數據寫入磁盤。
|
oprofpp |
檢索檔案數據。詳情請參閱第5.2 節。
|
op_import |
把樣品數據庫文件從異類二進制格式轉換成系統的本地原始格式。只有在分析不同體系的樣品數據庫時才使用該選項。
|
表1. OProfile 命令
第2節 配置 OProfile
在運行 OProfile 之前,它必須被配置。至少需要選擇是否要監視內核。以下各節描述了如何使用opcontrol 工具來配置 OProfile。在 opcontrol 命令被執行時,設置選項就會被保存到/root/.oprofile/daemonrc 文件中。
2.1. 指定內核
首先,配置 OProfile 是否應該監視內核。這是在啟動 OProfile 前唯一所需的配置選項。其它選項都是可選的。
要監視內核,以根用戶身份執行以下命令:
opcontrol --vmlinux=/boot/vmlinux-`uname -r`
|
要配置 OProfile 不監視內核,以根用戶身份執行以下命令:
這個命令還會載入 oprofile 內核模塊(如果還沒有被載入),並創建 /dev/oprofile/ 目錄(如果不存在)。關於這個目錄的詳情,請參閱第
43.6 節。
|
註記 |
|
即便 OProfile 被配置成不為內核建檔,SMP 內核仍舊必須運行,這樣,oprofile 模塊才會被載入。
|
設置樣品是否應在內核中收集只會改變所收集的數據,而不會改變收集數據的方法或貯存地點。要為內核和應用程序庫生成不同的樣品文件,請參閱第2.3
節。
2.2. 設置要監視的事件
多數處理器包含計數器(counters)。它們被 OProfile 用來監視指定的事件。如表
43-2所示,可用的計數器的數量要根據處理器而定。
處理器 |
cpu_type |
計數器數量 |
Pentium Pro |
i386/ppro |
2 |
Pentium II |
i386/pii |
2 |
Pentium III |
i386/piii |
2 |
Pentium 4 (無超線程) |
i386/p4 |
8 |
Pentium 4 (有超線程) |
i386/p4-ht |
4 |
Athlon |
i386/athlon |
4 |
AMD64 |
x86-64/hammer |
4 |
Itanium |
ia64/itanium |
4 |
Itanium 2 |
ia64/itanium2 |
4 |
TIMER_INT |
計時器(timer) |
1 |
IBM eServer iSeries |
計時器(timer) |
1 |
IBM eServer pSeries |
計時器(timer) |
1 |
IBM eServer S/390 |
計時器(timer) |
1 |
IBM eServer zSeries |
計時器(timer) |
1 |
表2. OProfile 處理器和計數器
使用表2的信息來校驗所檢測到的處理器類型是否正確,並且判定能夠被同時監視的事件數量。如果處理器沒有支持的性能監視硬件,計時器(timer)就會被用作處理器類型。
如果使用了 timer,事件就不能為任何處理器設置,因為硬件不支持硬件性能計數器。相反,計時器中斷會被用來建檔。
如果 timer 沒有被用作處理器類型,監視的事件就可以被改變,處理器的計數器0就會被默認設置為基於時間的事件。如果處理器上有多個計數器,0以外的計數器就不會被默認設置任何事件。被監視的默認事件顯示在表3中。
處理器 |
計數器0的默認事件 |
描述 |
Pentium Pro, Pentium II, Pentium III, Athlon, AMD64 |
CPU_CLK_UNHALTED |
處理器的時鐘沒有停止 |
Pentium 4 (HT 和非 HT) |
GLOBAL_POWER_EVENTS |
處理器沒有停止的時間 |
Itanium 2 |
CPU_CYCLES |
CPU 周期 |
TIMER_INT |
(none) |
每個計時器中斷的抽樣 |
表3. 默認事件
可以被同時監視的事件數量是由處理器的計數器數量決定的。不過,這不是一對一的情況;在某些處理器上,某些事件必須被映射到指定的計數器上。要判定可用的計數器數量,執行以下命令:
cat /dev/oprofile/cpu_type
|
可用的事件要根據處理器類型而定。要判定可被建檔的事件,以根用戶身份執行以下命令(該列表是針對系統處理器類型特有的):
每個計數器的事件都可以通過命令行被配置,也可以使用圖形化界面配置。如果計數器沒有被設置給指定的事件,錯誤消息就會被顯示。
要通過命令行來為每個可配置的計數器設置事件,使用 opcontrol:
opcontrol --ctrlN-event=<event-name>
|
把 N 替換成計數器號碼(從0開始),把 <event-name> 替換成 op_help 中顯示的確切事件名稱。
2.2.1. 抽樣率
默認設置會選擇基於時間的事件設置。它大約會創建每處理器每秒2000個樣品。如果使用了計時器中斷,計時器就被設置成兩幅畫面的最小時間間隔率,而且還不能被用戶設置。如果 cpu_type 不是 timer,每個事件就必須設置了一個抽樣率(sampling
rate)。抽樣率是每次抽樣之間發生的事件數量。
在為計數器設置事件時,還可以指定一個抽樣率:
opcontrol --ctrN-event=<event-name> --ctrN-count=<sample-rate>
|
把 <sample-rate> 替換成再次抽樣前要等待的事件數量。這個值越小,抽樣的頻率就越高。對於不常發生的事件,你可能需要使用一個較小的值才能捕獲事件實例。
|
小心 |
|
在設置抽樣率時務必小心。抽樣率太頻繁會使系統超載,導致系統似乎僵住或者真的僵住了。
|
2.2.2. 單元屏蔽
如果 cpu_type 不是 timer,那麽就可能還需要單元屏蔽(unit
masks)來進一步確定事件。
每個事件的單元屏蔽可以使用 op_help 命令列舉。每個單元屏蔽的值都以十六進制格式顯示。要指定一個以上單元屏蔽,十六進制的值必須使用逐位“或”(or)算符來組合。
opcontrol --ctrN-event=<event-name> --ctrN-count=<sample-rate> --ctrN-unit-mask=<value>
|
2.3. 分離內核和用戶空間檔案
按照默認設置,每個事件都收集內核模式和用戶模式的信息。要配置 OProfile 在某個指定的計數器中不計數內核模式的事件,執行以下命令(這裏的 N 是計數器號碼):
opcontrol --ctrN-kernel=0
|
執行以下命令來再次啟動計數器的建檔內核模式:
opcontrol --ctrN-kernel=1
|
要配置 OProfile 不計數某個指定計數器的用戶模式的事件,執行以下命令(這裏的 N 是計數器號碼):
執行以下命令來再次啟動計數器的建檔用戶模式:
當 OProfile 守護進程把檔案數據寫入樣品文件,它可以把內核和庫檔案的數據分成兩個單獨的樣品文件。要配置守護進程寫入樣品文件的方式,以根用戶身份執行以下命令:
opcontrol --separate=<choice>
|
<choice> 可以是以下之一:
如果 --separate=library 被使用,抽樣文件名在包括可執行文件名稱的同時還包括庫的名稱。
第3節 啟動和停止 OProfile
要使用 OProfile 來開始監視系統,以根用戶身份執行以下命令:
所顯示的輸出和下面相似:
Using log file /var/lib/oprofile/oprofiled.log
Daemon started.
Profiler running.
|
/root/.oprofile/daemonrc 中的設置被使用。
OProfile 守護進程 oprofiled 被啟動;它定期把樣品數據寫入 /var/lib/oprofile/samples/ 目錄。該守護進程的日誌位於 /var/lib/oprofile/oprofiled.log。
如果 OProfile 使用不同的配置選項被重新啟動,以前會話中的樣品文件就會被自動備份到/var/lib/oprofile/samples/session-N 目錄中,這裏的 N 是前一次備份會話數量再加1。
Backing up samples file to directory /var/lib/oprofile/samples//session-1
Using log file /var/lib/oprofile/oprofiled.log
Daemon started.
Profiler running.
|
要停止建檔器,以根用戶身份執行以下命令:
第4節 保存數據
有時,在指定時間保存樣品會很有用。例如,在給可執行文件建檔的時候,根據不同的輸入數據來收集不同的樣品可能會很有用。如果要監視的事件數量超過了處理器可用的計數器數量,你可以運行多次 OProfile 來收集數據,每次都把樣品數據保存到不同的文件中。
要保存當前的抽樣文件集合,執行以下命令,把 <name> 替換成當前會話中的獨特描述性名稱。
目錄 /var/lib/oprofile/samples/name/ 被創建,當前的抽樣文件被復制到其中。
第5節 分析數據
OProfile 守護進程 oprofiled 定期收集樣品,並把它們寫入 /var/lib/oprofile/samples/ 目錄。在讀取數據之前,請以根用戶身份執行以下命令來確定所有數據都被寫入這個目錄中了:
每個樣品文件名稱都基於可執行文件的名稱,使用右括號(})來代替每個正斜線(/)。文件名的結尾是井號(#)和用於該樣品文件的計數器號碼。例如,以下文件包括了計數器0所收集的 /sbin/syslogd 這個可執行文件的樣品數據:
一旦抽樣數據被收集,你可以使用以下工具來分析它們: