使用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 就可以了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453047.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453047.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453047.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是死鎖

死鎖是多個進程在運行過程中因競爭資源時產生的一種僵局。 各并發資源彼此等待對方擁有的資源&#xff0c;且在得到對方資源前不釋放自己的資源。

python數據工程師 面試題_阿里P7工程師耗時兩天整理的292道python大廠面試題,內含解析!...

前言相對于python大家應該都不會陌生吧&#xff01;現在java跟python可以算的是勢均力敵了&#xff0c;所以現在學習python 的小伙伴也是越來越多了&#xff0c;可是學完之后就能找到稱心如意的工作了嗎&#xff1f;很多小伙伴學習Python的時候感覺很簡單&#xff0c;但是到了去…

數組復制

在Java里面,可以用復制語句”AB”給基本類型的數據傳遞值,但是如果A,B是兩個同類型的數組&#xff0c;復制就相當于將一個數組變量的引用傳遞給另一個數組&#xff1b;如果一個數組發生改變&#xff0c;那么引用同一數組的變量也要發生改變。 1.使用FOR循環,將數組的每個元素復…

IntelliJ IDEA 對于generated source的處理

IntelliJ IDEA 對于generated source的處理 學習了&#xff1a;https://stackoverflow.com/questions/5170620/unable-to-use-intellij-with-a-generated-sources-folder 如果有generated source &#xff0c;例如使用gRPC過程中生成的&#xff0c;可以使用鼠標右鍵點擊使之成為…

產生死鎖的原因

一 競爭資源&#xff0c;但是資源的數目不能滿足進程的需要。 二 進程間推進順序非法&#xff0c;進程在運行過程中請求和釋放資源的順序不當。

fabric shim安裝合約_hyperledger fabric 開發第一個智能合約

一、編寫智能合約代碼HelloWorld.go&#xff0c;go語言實現&#xff0c;代碼很簡單&#xff0c;每個合約包含兩個方法&#xff0c;Init、Invoke。package mainimport ("fmt""github.com/hyperledger/fabric/core/chaincode/shim""github.com/hyperled…

不能干一輩子開發???

程序員的職業生涯之我見 總是聽到下面的論調 程序員干不了一輩子&#xff01; 程序員怎么也不能干一輩子吧&#xff01; 在中國程序員還能干一輩子&#xff1f; 過了&#xff08;30&#xff09;40我就干不動程序員了&#xff01; 每每聽…

分布式緩存的25個優秀實踐與線上案例 done

楊彪&#xff0c;螞蟻金服技術專家&#xff0c;《分布式服務架構&#xff1a;原理、設計與實戰》和《可伸縮服務架構&#xff1a;框架與中間件》作者。近10年互聯網和游戲行業工作經驗。本文節選自即將出版的《可伸縮服務架構&#xff1a;框架與中間件》一書&#xff0c;作者&a…

服務器性能估算參考(硬件-應用服務器)

2019獨角獸企業重金招聘Python工程師標準>>> Environment(2013-05-24) two identical machines via a GB-Ethernet link a client machine generating HTTP requests with wrk as the load generator a server machine running the respective “benchmarkee”all …

產生死鎖的四個必要條件

&#xff08;1&#xff09;互斥條件&#xff1a;進程對所分配到的資源不允許其他進程進行訪問&#xff0c;若其他進程訪問該資源&#xff0c;只能等待&#xff0c;直至占有該資源的進程使用完成后釋放該資源 &#xff08;2&#xff09;請求和保持條件&#xff1a;進程獲得一定的…

下拉選擇_在管理Excel中實現聯動下拉選擇

在系統中常常出現這樣的情況&#xff1a;由于下拉選擇的數量太多了&#xff0c;難以高效選擇。為此管理Excel通過通過引入多級聯動選擇的方式來減少下拉選擇的困難度。先看下使用效果&#xff1a;聯動下拉選擇這個功能&#xff0c;在管理Excel中可以通過比較簡單的配置方法實現…

圖片預覽

// 預覽圖片yulanFn: function (e) {var arr [];var that this;//獲取當前圖片的下表var indexw e.currentTarget.dataset.indexw;var index e.currentTarget.dataset.index;//數據源var pictures this.data.banner[indexw].shoppingCarouselList;var picture "http…

風雨20年:我所積累的20條編程經驗

原文作者喬納森丹尼可&#xff08;Jonathan Danylko&#xff09;是一位自由職業的web架構師和程序員&#xff0c;編程經驗已超過20年&#xff0c;涉足領域有電子商務、生物技術、房地產、醫療、保險和公用事業。正如喬納 森在文中所言&#xff0c;本文適合剛畢業的大學生和剛入…

JS跨域(ajax跨域、iframe跨域)解決方法及原理詳解(jsonp)

這里說的js跨域是指通過js在不同的域之間進行數據傳輸或通信&#xff0c;比如用ajax向一個不同的域請求數據&#xff0c;或者通過js獲取頁面中不同域的框架中(iframe)的數據。只要協議、域名、端口有任何一個不同&#xff0c;都被當作是不同的域。 下表給出了相對 http://store…

xenserver 安裝新硬盤_給Xenserver添加新硬盤

首先我們進入到xenserver的Console界面.然后按下enter進入命令模式,接下來.咱們先看看硬盤有沒有存在輸入fdisk -l出現如下提示:Disk /dev/sda: 500.1 GB, 500107862016 bytes255 heads, 63 sectors/track, 60801 cylindersUnits cylinders of 16065 * 512 8225280 bytesDevi…

go-study

package (包) 一個目錄下面所有的.go文件的包名必須相同. 包名一般和目錄名相同(是約定, 不是強制), 包名都小寫main包是一個特殊的包名, 在main包中, 必須包含func main()函數導入包(import)的時候, 使用的是包所在目錄的路徑, 路徑中不用包含包的名字, 在使用包的時候,直接用…

什么是系統安全狀態

指系統能按某種順序如&#xff08;P1&#xff0c;P2&#xff0c;...&#xff0c;Pn&#xff09;&#xff0c;來為每個進程分配所需要的資源&#xff0c;直至最大需求&#xff0c;使每個進程都可以順序完成。若系統不存在這樣一個安全序列&#xff0c;則稱系統處于不安全狀態。

SQL零基礎學習筆記(一)

真的不知道我寫了這么多不同的的學習筆記又沒用。。開始SQL零基礎學習筆記 百度百科&#xff1a;SQL&#xff08;Structured Query Language)結構化查詢語言&#xff0c;是一種數據庫查詢和程序設計語言&#xff0c;用于存取數據以及查詢、更新和管理關系數據庫系統。同時也是數…

WPF 列表虛擬化時的滾動方式

ListBox的滾動方式 分為像素滾動和列表項滾動 通過ListBox的附加屬性ScrollViewer.CanContentScroll來設置。因此ListBox的默認模板中&#xff0c;含有ScrollViewer&#xff0c;ScrollViewer下存放列表內容 <ScrollViewer FocusVisualStyle"{x:Null}"><Item…