《Linux調優工具oprofile的演示分析》


根據CPU架構oprofile采樣的觸發有兩種模式:
1) NMI模式: 利用處理器的performance counter功能, 指定counter的類型type和累進數量count. 比如

type=DTLB_MISS, count=500, 代表"Data TLB miss"每發生500次, 會觸發一次中斷. Oprofile.ko模塊會相應這個中斷, 然后看當前正在執行的是什么指令,那個函數, 那個模塊(或者app, lib), 並進行計數. 不同的處理器支持的counter類型和count取值范圍各不相同. 可以通過ophelp來查看當前cpu所支持的counter類型和參數. 例如, "--event=MISALIGN_MEM_REF:1000:0:1:0"表示非對齊的內存訪問, 每1000次觸發一個中斷, 1000后面的0表示改特定counter的mask, 具體含義看ophelp的內容; 最后的1:0表示只對kernel采樣, 不對用戶空間程序采樣. "--event=CPU_CLK_UNHALTED:10000:0:1:0"代表cpu時鍾周期事件.每10000個cycle觸發一次中斷. "--event=L1I_MISSES:500:0:1:0"表示一級指令緩存的cache miss.


2) Timer Interrupt模式: 在沒有performance counter支持的情況下(例如Vmware虛擬機下), 可以利用時鍾中斷來采樣. 這時候就沒有performance counter的概念了. 或者可以當成近似的cpu時鍾周期事件. 要使用timer interrupt模式, 需要在加載oprofile.ko模塊的時候,傳遞"timer=1"參數. modprobe oprofile timer=1

 

一)用opcontrol控制profile
要打開oprofile,需要用start選項來調用opconrol,當第一次調用opcontrol時,必須告訴它想統計內核還是用戶空間數據.
因為我們的例子是在用戶空間工作,應該用--no-vmlinux選項來取消內核統計,如下:

1.首先需要加載profile:

opcontrol --init

初始化oprofile,可以通過demsg查看oprofile使用的是哪一種模式:
[root@compiler /]# dmesg | grep oprofile
oprofile: using NMI interrupt.
oprofile: using NMI interrupt.
oprofile: using NMI interrupt.
oprofile: using NMI interrupt.
oprofile: using NMI interrupt.

 

2.然后start 調用開始獲取CPU采樣:


[root@compiler /]# opcontrol --start --no-vmlinux
ATTENTION: Use of opcontrol is discouraged. Please see the man page for operf.
Using default event: CPU_CLK_UNHALTED:100000:0:1:1
Using 2.6+ OProfile kernel interface.
Using log file /var/lib/oprofile/samples/oprofiled.log
Daemon started.
Profiler running.


每次啟動都會在/root/.oprofile/目錄下生成一個配置文件daemonrc,如下:

[root@compiler /]# cat /root/.oprofile/daemonrc
SESSION_DIR=/var/lib/oprofile
NR_CHOSEN=0
SEPARATE_LIB=0
SEPARATE_KERNEL=0
SEPARATE_THREAD=0
SEPARATE_CPU=0
VMLINUX=none
IMAGE_FILTER=
CPU_BUF_SIZE=0
CALLGRAPH=0
XENIMAGE=none

注:
以上的每個配置項是通過啟動oprofile時加的參數生成的.

 

清理統計數據,重置統計量,如下:
[root@compiler /]# opcontrol --reset


3.這個時候啟動需要監控的程序,如果是內核,就直接sleep一段時間即可

[root@compiler /]# /usr/local/nginx/sbin/nginx

 

4.接下來我們用--dump選項告訴oprofiled輸出統計量,如下:
[root@compiler /]# opcontrol --dump

(可選)停止后台程序
[root@compiler /]# opcontrol --shutdown

 

5.再下來我們就可以用opreport,opgprof或者opannotate來觀察它們,任何用戶都可以看到輸出,下面我們用opreport來查看統計量,如下:
(1)opreport

[root@compiler /]# opreport |grep nginx
Using /var/lib/oprofile/samples/ for samples directory.
39 1.0e-04 nginx

觀察對應進程里面函數在運行時候的的占用百分比
[root@compiler /]# opreport -l /usr/local/nginx/sbin/nginx
Using /var/lib/oprofile/samples/ for samples directory.
CPU: Intel Core/i7, speed 2.128e+06 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (No unit mask) count 100000
samples % symbol name
20 39.2157 ngx_hash_init
10 19.6078 ngx_conf_parse
2 3.9216 ngx_init_setproctitle
1 1.9608 _fini
1 1.9608 main
1 1.9608 ngx_array_push
1 1.9608 ngx_cpuinfo
1 1.9608 ngx_event_process_init
1 1.9608 ngx_hash_key_lc
1 1.9608 ngx_http_core_merge_loc_conf
1 1.9608 ngx_http_core_server_name
1 1.9608 ngx_http_core_type
1 1.9608 ngx_http_limit_conn_merge_conf
1 1.9608 ngx_http_log_compile_format
1 1.9608 ngx_http_log_init
1 1.9608 ngx_http_merge_locations
1 1.9608 ngx_http_upstream_keepalive_create_conf
1 1.9608 ngx_http_uwsgi_merge_loc_conf
1 1.9608 ngx_signal_handler
1 1.9608 ngx_strlow
1 1.9608 ngx_vslprintf
1 1.9608 ngx_worker_process_init
[root@compiler /]#


(2)opannotate
[root@compiler /]# opannotate --source /usr/local/nginx/sbin/nginx > 1.txt

可以針對某一個進程,里面所有函數的執行采樣統計,用於優化函數。

        
注:
輸出顯示了一系列對象文件,文件包含了當profile測試時正在運行的代碼.
oprofiled 從調用opcontrol --start時開始記錄,到調用opcontrol --dump時會截取當前的統計量,但是oprofiled仍會繼續搜集並積累統計數據,之后再調用opconrol --dump就會有舊的積累數據產生.直到調用opcontrol --stop時,才會停止搜集.

 

(3)opgprof

我們可以通過gprof來產生一個gmon.out文件,如下:
[root@compiler /]# opgprof /usr/local/nginx/sbin/nginx

不調用圖像數據得出gmon.out結果

[root@compiler /]# gprof --no-graph /usr/local/nginx/sbin/nginx
Flat profile:

Each sample counts as 1 samples.
% cumulative self self total
time samples samples calls T1/call T1/call name
39.22 20.00 20.00 ngx_hash_init
19.61 30.00 10.00 ngx_conf_parse
3.92 32.00 2.00 ngx_init_setproctitle
1.96 33.00 1.00 _fini
1.96 34.00 1.00 main
1.96 35.00 1.00 ngx_array_push
1.96 36.00 1.00 ngx_cpuinfo
1.96 37.00 1.00 ngx_event_process_init
1.96 38.00 1.00 ngx_hash_key_lc
1.96 39.00 1.00 ngx_http_core_merge_loc_conf
1.96 40.00 1.00 ngx_http_core_server_name
1.96 41.00 1.00 ngx_http_core_type
1.96 42.00 1.00 ngx_http_limit_conn_merge_conf
1.96 43.00 1.00 ngx_http_log_compile_format
1.96 44.00 1.00 ngx_http_log_init
1.96 45.00 1.00 ngx_http_merge_locations
1.96 46.00 1.00 ngx_http_upstream_keepalive_create_conf
1.96 47.00 1.00 ngx_http_uwsgi_merge_loc_conf
1.96 48.00 1.00 ngx_signal_handler
1.96 49.00 1.00 ngx_strlow
1.96 50.00 1.00 ngx_vslprintf
1.96 51.00 1.00 ngx_worker_process_init

% the percentage of the total running time of the
time program used by this function.

cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.

self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.

calls the number of times this function was invoked, if
this function is profiled, else blank.

self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.

total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.

name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
[root@compiler /]#

 

6.
opcontrol --stop  #停止profiling
opcontrol --shutdown  #關閉守護進程oprofiled
opcontrol --deinit  #卸載模塊

 

 

二)關於oprofile的最終論述

這里只提到了oprofile的表面功能.
默認情況下,oprofile不支持在虛擬機上進行調試,我們可以通過下面的方法讓oprofile可以在虛擬機上跑,如下:


echo "options oprofile timer=1" >> /etc/modprobe.conf
此時再重啟虛擬機就可以工作了.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM