使用gperftools對程序進行性能分析

使用gperftools對程序進行性能分析

gperftools是google出品的一個性能分析工具,相關介紹可見:
https://github.com/gperftools/gperftools/wiki
gperftools性能分析經過抽樣方法完成,默認是1秒100個樣本,即一個樣本是10毫秒,所以程序運行時間要長一些。git

一、安裝gperftools

1.一、安裝automake

sudo apt-get install automakegithub

1.二、編譯安裝libunwind

從https://github.com/libunwind/libunwind/releases下載最新版本的libunwind源碼包
解壓到/usr/local/src目錄
cd 解壓源碼目錄
./autogen.sh
./configure
make -j6
make installubuntu

1.三、編譯安裝gperftools

從https://github.com/gperftools/gperftools/releases下載最新版本的gperftools源碼包
解壓到/usr/local/src目錄
cd 解壓源碼目錄
./autogen.sh
./configure
make -j6
make installide

1.四、安裝圖像分析生成工具

sudo apt-get install graphviz函數

二、使用

2.一、運行一段時間就會正常退出的程序的性能分析

這種狀況,咱們能夠直接在代碼中插入性能分析函數。示例代碼以下:工具

#include <gperftools/profiler.h>
#include <stdlib.h>

void f()
{
    int i; 
    for (i=0; i<1024*1024; ++i)
    {  
        char *p = (char*)malloc(1024*1024*120);
        free(p);
    }  
}

int main()
{
    ProfilerStart("test.prof");//開啓性能分析
    f();
    ProfilerStop();//中止性能分析
    return 0; 
}

編譯運行,注意編譯時須要鏈接tcmalloc和profiler庫。運行後會生成test.prof文件,而後用pprof就能夠生成text的分析報告,具體以下:性能

root@ubuntu:/home/zte/test/perf# gcc not_run_alway.c -ltcmalloc -lprofiler
root@ubuntu:/home/zte/test/perf# ./a.out 
PROFILE: interrupts/evictions/bytes = 14/0/776
root@ubuntu:/home/zte/test/perf# pprof --text a.out test.prof 
Using local file a.out.
Using local file test.prof.
Total: 14 samples
       3  21.4%  21.4%        3  21.4% SpinLock::Unlock (inline)
       3  21.4%  42.9%        3  21.4% __GI_madvise
       2  14.3%  57.1%        2  14.3% SpinLock::Lock (inline)
       1   7.1%  64.3%        1   7.1% TCMalloc_PageMap2::get (inline)
       1   7.1%  71.4%        4  28.6% do_malloc_pages
       1   7.1%  78.6%        2  14.3% tcmalloc::PageHeap::Delete
       1   7.1%  85.7%        2  14.3% tcmalloc::PageHeap::New
       1   7.1%  92.9%        4  28.6% tcmalloc::PageHeap::ReleaseAtLeastNPages
       1   7.1% 100.0%        1   7.1% tcmalloc::PageHeap::RemoveFromFreeList
       0   0.0% 100.0%        2  14.3% SpinLockHolder (inline)
       0   0.0% 100.0%        3  21.4% TCMalloc_SystemRelease
       0   0.0% 100.0%       14 100.0% __libc_start_main
       0   0.0% 100.0%       14 100.0% _start
       0   0.0% 100.0%        4  28.6% do_allocate_full (inline)
       0   0.0% 100.0%       10  71.4% do_free_pages
       0   0.0% 100.0%        4  28.6% do_malloc (inline)
       0   0.0% 100.0%       14 100.0% f
       0   0.0% 100.0%       14 100.0% main
       0   0.0% 100.0%        1   7.1% tcmalloc::PageHeap::Carve
       0   0.0% 100.0%        3  21.4% tcmalloc::PageHeap::DecommitSpan
       0   0.0% 100.0%        1   7.1% tcmalloc::PageHeap::GetDescriptor (inline)
       0   0.0% 100.0%        4  28.6% tcmalloc::PageHeap::IncrementalScavenge
       0   0.0% 100.0%        1   7.1% tcmalloc::PageHeap::MergeIntoFreeList
       0   0.0% 100.0%        3  21.4% tcmalloc::PageHeap::ReleaseLastNormalSpan
       0   0.0% 100.0%        4  28.6% tcmalloc::allocate_full_malloc_oom
       0   0.0% 100.0%        3  21.4% ~SpinLockHolder (inline)

輸出數據解析:
每行包含6列數據,依次爲:
1 分析樣本數量(不包含其餘函數調用)
2 分析樣本百分比(不包含其餘函數調用)
3 目前爲止的分析樣本百分比(不包含其餘函數調用)
4 分析樣本數量(包含其餘函數調用)
5 分析樣本百分比(包含其餘函數調用)
6 函數名 google

樣本數量至關於消耗的CPU時間。
整個函數消耗的CPU時間至關於包括函數內部其餘函數調用所消耗的CPU時間 code

運行命令生成函數調用樹形式的pdf分析報告:
pprof --pdf a.out test.prof >test.pdf
使用gperftools對程序進行性能分析
樹上的每一個節點表明一個函數,節點數據格式:
一、函數名 或者 類名+方法名
二、不包含內部函數調用的樣本數 (百分比)
三、of 包含內部函數調用的樣本數 (百分比) #若是沒有內部調用函數則這一項數據不顯示orm

2.2 一直運行的程序的性能分析

一直運行的程序因爲不能正常退出,因此不能採用上面的方法。咱們能夠用信號量來開啓/關閉性能分析,具體代碼以下:

#include <gperftools/profiler.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>

void gprofStartAndStop(int signum) {
    static int isStarted = 0;
    if (signum != SIGUSR1) return;

    //經過isStarted標記將來控制第一次收到信號量開啓性能分析,第二次收到關閉性能分析。
    if (!isStarted){
        isStarted = 1;
        ProfilerStart("test.prof");
        printf("ProfilerStart success\n");
    }else{
        ProfilerStop();
        printf("ProfilerStop success\n");
    }
}

void f()
{
    int i;
    for (i=0; i<1024*1024; ++i)
    {
        char *p = (char*)malloc(1024*1024);
        free(p);
    }
}

int main()
{
    signal(SIGUSR1, gprofStartAndStop);

    while(1){
        printf("call f\n");
        f();
        sleep(1);//爲了防止死循環,致使信號處理函數得不到調度
    }
    return 0;
}

編譯運行以下:

root@ubuntu:/home/zte/test/perf# gcc run_always.c -ltcmalloc -lprofiler
root@ubuntu:/home/zte/test/perf# ./a.out

經過kill命令發送信號給進程來開啓/關閉性能分析:
用top命令查看進程的PID
kill -s SIGUSR1 PID //第一次運行命令啓動性能分析
kill -s SIGUSR1 PID //再次運行命令關閉性能分析,產生test.prof

後續分析報告生成同2.1,再也不贅述。

相關文章
相關標籤/搜索