日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用oprofile分析性能瓶颈

發布時間:2023/12/18 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用oprofile分析性能瓶颈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用oprofile分析性能瓶頸

1. 概述

oprofile 是 Linux 平臺上,類似 INTEL VTune 的一個功能強大的性能分析工具。

其支持兩種采樣(sampling)方式:基于事件的采樣(event based)和基于時間的采樣(time based)。

基于事件的采樣是oprofile只記錄特定事件(比如L2 cache miss)的發生次數,當達到用戶設定的
定值時oprofile 就記錄一下(采一個樣)。這種方式需要CPU 內部有性能計數器(performace counter)。
現代CPU內部一般都有性能計數器,龍芯2E內部亦內置了2個性能計數器。

基于時間的采樣是oprofile 借助OS 時鐘中斷的機制,每個時鐘中斷 oprofile 都會記錄一次(采一次樣)。
引入的目的在于,提供對沒有性能計數器 CPU 的支持。其精度相對于基于事件的采樣要低。因為要借助 OS
時鐘中斷的支持,對禁用中斷的代碼oprofile不能對其進行分析。

oprofile 在Linux 上分兩部分,一個是內核模塊(oprofile.ko),一個為用戶空間的守護進程(oprofiled)。
前者負責訪問性能計數器或者注冊基于時間采樣的函數(使用register_timer_hook注冊之,使時鐘中斷處理
程序最后執行profile_tick 時可以訪問之),并采樣置于內核的緩沖區內。后者在后臺運行,負責從內核空
間收集數據,寫入文件。


2. oprofile 的安裝

以龍芯2E平臺為例,要使用oprofile 首先得采用打開oprofile支持的內核啟動。然后安裝下面3個軟件包:
oprofile, oprofile-common, oprofile-gui,其中核心軟件包是oprofile-common,其包括以下工具集:

? ? ? ? /usr/bin/oprofiled? ? ? ? ? ? ? ? 守護進程
? ? ? ? /usr/bin/opcontrol? ? ? ? ? ? ? ? 控制前端,負責控制與用戶交互,用得最多? ? ? ?
? ? ? ? /usr/bin/opannotate? ? ? ? ? ? ? ? 根據搜集到的數據,在源碼或者匯編層面上注釋并呈現給用戶
? ? ? ? /usr/bin/opreport? ? ? ? ? ? ? ? 生成二進制鏡像或符號的概覽
? ? ? ? /usr/bin/ophelp? ? ? ? ? ? ? ? ? ? ? ? 列出oprofile支持的事件
? ? ? ? /usr/bin/opgprof? ? ? ? ? ? ? ? 生成gprof格式的剖析數據
? ? ? ? ...


目前oprofile 在龍芯2E上已經移植好了,包括用戶空間的工具集軟件包,亦可用矣。

一個測試用的內核,已經打開 oprofile ,位于 http://people.openrays.org/~comcat/godson/vmlinux-2.6.18-oprofile

用戶空間工具集deb 包位于: http://people.openrays.org/~comcat/godson/oprofile-0.9.2/


3. oprofile 快速上手

a. 初始化

? ? ? ? opcontrol --init

? ? ? ? 該命令會加載oprofile.ko模塊,mount oprofilefs。成功后會在/dev/oprofile/目錄下導出
? ? ? ? 一些文件和目錄如: cpu_type, dump, enable, pointer_size, stats/

b. 配置

? ? ? ? 主要設置計數事件和樣本計數,以及計數的CPU模式(用戶態、核心態)
? ? ? ?
? ? ? ? opcontrol --setup --event=CYCLES:1000::0:1

? ? ? ? 則是設置計數事件為CYCLES,即對處理器時鐘周期進行計數
? ? ? ? 樣本計數為1000,即每1000個時鐘周期,oprofile 取樣一次。
? ? ? ? 處理器運行于核心態則不計數
? ? ? ? 運行于用戶態則計數

? ? ? ? --event=name:count:unitmask:kernel:user

? ?? ?name:? ???event name, e.g. CYCLES or ICACHE_MISSES
? ?? ?count:? ? reset counter value e.g. 100000
? ?? ?unitmask: hardware unit mask e.g. 0x0f
? ?? ?kernel:? ?whether to profile kernel: 0 or 1
? ?? ?user:? ???whether to profile userspace: 0 or 1

c. 啟動

? ? ? ? opcontrol --start


d. 運行待分析之程序

? ? ? ? ./ffmpeg -c cif -vcodec mpeg4 -i /root/paris.yuv paris.avi

e. 取出數據

? ? ? ? opcontrol --dump
? ? ? ? opcontrol --stop

f. 分析結果

? ? ? ? opreport -l ./ffmpeg


則會輸出如下結果:

CPU: GODSON2E, speed 0 MHz (estimated)
Counted CYCLES events (Cycles) with a unit mask of 0x00 (No unit mask) count 10000
samples??%? ?? ???symbol name
11739? ? 27.0148??pix_abs16_c
6052? ???13.9274??pix_abs16_xy2_c
4439? ???10.2154??ff_jpeg_fdct_islow
2574? ?? ?5.9235??pix_abs16_y2_c
2555? ?? ?5.8798??dct_quantize_c
2514? ?? ?5.7854??pix_abs8_c
2358? ?? ?5.4264??pix_abs16_x2_c
1388? ?? ?3.1942??diff_pixels_c
964? ?? ? 2.2184??ff_estimate_p_frame_motion
852? ?? ? 1.9607??simple_idct_add
768? ?? ? 1.7674??sse16_c
751? ?? ? 1.7283??ff_epzs_motion_search
735? ?? ? 1.6914??pix_norm1_c
619? ?? ? 1.4245??pix_sum_c
561? ?? ? 1.2910??mpeg4_encode_blocks
558? ?? ? 1.2841??encode_thread
269? ?? ? 0.6190??put_no_rnd_pixels16_c
255? ?? ? 0.5868??dct_unquantize_h263_inter_c

......


4. 例子

oprofile 可以分析處理器周期、TLB 失誤、分支預測失誤、緩存失誤、中斷處理程序,等等。
你可以使用 opcontrol --list-events 列出當前處理器上可監視事件列表。

下面分析一個編寫不當的例子:


[帶有cache問題的代碼cache.c]
+++++++++++++++++++++++++++++++++++++++++++++++

int matrix[2047][7];


void bad_access()
{
? ? int k, j, sum = 0;

? ? for(k = 0; k < 7; k++)
? ?? ???for(j = 0; j < 2047; j++)
? ?? ?? ?? ?sum += matrix[j][k] * 1024;

}

int main()
{
? ? ? ? int i;

? ? ? ? for(i = 0; i< 100000; i++)
? ? ? ? ? ? ? ? bad_access();

? ? ? ? return 0;

}

+++++++++++++++++++++++++++++++++++++++++++++++


編譯之: gcc -g cache.c -o cache


使用oprofile 分析之:

opcontrol --init

opcontrol --setup --event=DCACHE_MISSES:500::0:1

opcontrol --start && ./cache && opcontrol --dump && opcontrol --stop


使用 opannotate 分析結果為:

/*
* Command line: opannotate --source ./cachee
*
* Interpretation of command line:
* Output annotated source file with samples
* Output all files
*
* CPU: GODSON2E, speed 0 MHz (estimated)
* Counted ICACHE_MISSES events (Instruction Cache misses number ) with a unit mask of 0x00 (No unit mask) count 500
*/
/*
* Total samples for file : "/comcat/test/pmc.test/cachee.c"
*
*? ???34 100.000
*/


? ?? ?? ?? ?? ?:int matrix[2047][7];
? ?? ?? ?? ?? ?:
? ?? ?? ?? ?? ?:void bad_access()
? ?? ?? ?? ?? ?:{ /* bad_access total:? ???33 97.0588 */
? ?? ?? ?? ?? ?:? ? int k, j, sum = 0;
? ?? ?? ?? ?? ?:
? ?? ?? ?? ?? ?:? ? for(k = 0; k < 7; k++)
? ? 33 97.0588 :? ?? ???for(j = 0; j < 2047; j++)
? ?? ?? ?? ?? ?:? ?? ?? ?? ?sum += matrix[j][k] * 1024;
? ?? ?? ?? ?? ?:
? ?? ?? ?? ?? ?:}
? ?? ?? ?? ?? ?:
? ?? ?? ?? ?? ?:int main()
? ?? ?? ?? ?? ?:{ /* main total:? ?? ?1??2.9412 */
? ?? ?? ?? ?? ?:? ? int i;
? ?? ?? ?? ?? ?:
? ???1??2.9412 :? ? for(i = 0; i< 10000; i++)
? ?? ?? ?? ?? ?:? ?? ?? ?? ?? ? bad_access();
? ?? ?? ?? ?? ?:
? ?? ?? ?? ?? ?:? ? return 0;
? ?? ?? ?? ?? ?:
? ?? ?? ?? ?? ?:}
? ?? ?? ?? ?? ?:


opreport 解析的結果為:

GodSonSmall:/comcat/test/pmc.test# opreport -l ./cache
CPU: GODSON2E, speed 0 MHz (estimated)
Counted ICACHE_MISSES events (Instruction Cache misses number ) with a unit mask of 0x00 (No unit mask) count 500
samples??%? ?? ???symbol name
33? ?? ? 97.0588??bad_access
1? ?? ?? ?2.9412??main

可以看到bad_access() cache miss 事件的樣本共有33個,占總數的97%


改進 bad_access() 為 good_access() 后:

void good_access()
{
? ? int k, j, sum = 0;

? ? for(k = 0; k < 2047; k++)
? ?? ???for(j = 0; j < 7; j++)
? ?? ?? ?? ?sum += matrix[k][j] * 1024;

}


CPU: GODSON2E, speed 0 MHz (estimated)
Counted ICACHE_MISSES events (Instruction Cache misses number ) with a unit mask of 0x00 (No unit mask) count 500
samples??%? ?? ???symbol name
22? ?? ? 95.6522??good_access
1? ?? ?? ?4.3478??main

可以看到改進后 cache miss 事件的樣本減少為22個,占總數的95%
可以使用gprof, 編譯你程序時加 -pg -g

運行之會在當前目錄產生 gmon.out

gprof ./your_program_name

就可以看到了

----------------------------------------

使用oprofile 更精確:

opcontrol --reset
opcontrol --init
opcontrol --setup --event=CYCLES:1000
opcontrol --start && ./your_program_name && opcontrol --dump && opcontrol --stop

opreport -l ./your_program_name

就可以看到了,使用oprofile,編譯時只要加 -g 就可以了

總結

以上是生活随笔為你收集整理的使用oprofile分析性能瓶颈的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。