首頁 > 軟體

Linux下gprof和oprofiling效能測試工具

2020-06-16 17:58:31

一、簡介

有些時候,我們特別關注程式的效能,特別是底層軟體,比如驅動程式,OS等。為了更好的優化程式效能,我們必須找到效能瓶頸點,“好鋼用在刀刃上”才能取 得好的效果,否則可能白做工作。為了找到關鍵路徑,我們可以使用profilng技術,在linux平台上,我們可以使用gprof和oprofile工 具。

gprof是GNU工具之一,它在編譯的時候在每個函數的出入口加入了profiling的程式碼,執行時統計程式在使用者態的 執行資訊,可以得到每個函數的呼叫次數,執行時間,呼叫關係等資訊,簡單易懂。適合於查詢使用者級程式的效能瓶頸,對於很多時間都在核心態執行的程 序,gprof不適合。

oProfile是Linux平台上的一個功能強大的效能分析工具,支援兩種取樣(sampling)方式:基於事件的取樣(eventbased)和基於時間的取樣(timebased),它可以工作在不同的體系結構上,包括MIPS、ARM、IA32、IA64和AMD。

二、gprof使用方法

gprof是gnu binutils工具之一,預設情況下linux系統當中都帶有這個工具

使用 -pg 選項來編譯hello.c,如果要得到帶注釋的原始碼清單,則需要增加 -g 選項。執行: gcc -pg -g -o hello hello.c
執行應用程式: ./hello 會在當前目錄下產生gmon.out檔案,使用gprof來分析gmon.out檔案時,需要把它和產生它的應用程式關聯起來:

gprof hello gmon.out -p 得到每個函數占用的執行時間
gprof hello gmon.out -q 得到call graph,包含了每個函數的呼叫關係,呼叫次數,執行時間等資訊。
gprof hello gmon.out -A 得到 一個帶注釋的“原始碼清單”,它會注釋原始碼,指出每個函數的執行次數。這需要在編譯的時候增加 -g選項。

三、oprofile安裝步驟

1、開啟核心OPROFILE選項,否則執行oProfile將提示:

[root@localhost oprofile-0.9.6]# opcontrol --init
FATAL: Module oprofile not found.
FATAL: Module oprofile not found.
Kernel doesn't support oprofile
2、編輯核心組態檔:.config,將其中的# CONFIG_OPROFILE is not set改為CONFIG_OPROFILE=m(或者y)
[root@localhost ~]# cd /usr/src/linux-2.6.37.2
[root@localhost linux-2.6.37.2]# vi .config

如下:

CONFIG_PROFILING=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_PCI_IOAPIC=y

3、編譯核心並重新啟動機器

4、下載原始碼,編譯安裝

wget http://cznic.dl.sourceforge.net/project/oprofile/oprofile/oprofile-1.0.0/oprofile-1.0.0.tar.gz
tar -zxvf oprofile-1.0.0.tar.gz
cd oprofile-1.0.0
./configure
make
make install

四、oprofile工具集

op_help:    列出所有支援的事件。
opcontrol:  設定需要收集的事件。
opreport:  對結果進行統計輸出。
opannaotate:產生帶注釋的源/組合檔案,源語言級的註釋需要編譯原始檔時的支援。
opstack:    產生呼叫圖profile,但要求x86/2.6的平台,並且linux2.6安裝了call-graph patch
opgprof:    產生如gprof相似的結果。
oparchive:  將所有的原始資料檔案收集打包,可以到另一台機器上進行分析。
op_import:  將取樣的資料庫檔案從另一種abi轉化成本地格式。

五、oprofile使用方法

測試檔案:multiply.c

#include <stdio.h>
int fast_multiply(x,  y)
{
    return x * y;
}
 
int slow_multiply(x, y)
{
    int i, j, z;
    for (i = 0, z = 0; i < x; i++)
        z = z + y;
    return z;
}
 
int main(int argc, char *argv[])
{
    int i,j;
    int x,y;
    for (i = 0; i < 200; i ++) {
        for (j = 0; j <  30 ; j++) {
            x = fast_multiply(i, j);
            y = slow_multiply(i, j);
        }
    }
    printf("x=%d, y=%dn", x, y);
    return 0;
}

編譯

gcc multiply.c -g -o multiply

測試

modprobe oprofile timer=1
opcontrol --no-vmlinux
opcontrol --separate=kernel
opcontrol --init
opcontrol --reset
opcontrol --start
./multiply
opcontrol --dump
opcontrol --stop
opcontrol --shutdown
opcontrol --deinit
opannotate --source ./multiply


opreport -l ./multiply


opreport

本文永久更新連結地址http://www.linuxidc.com/Linux/2015-06/118874.htm


IT145.com E-mail:sddin#qq.com