根據CPU架構oprofile採樣的觸發有兩種模式:
1) NMI模式: 利用處理器的performance counter功能, 指定counter的類型type和累進數量count. 好比linux
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.nginx
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:app
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.ui
每次啓動都會在/root/.oprofile/目錄下生成一個配置文件daemonrc,以下:this
[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此時再重啓虛擬機就能夠工做了.