您现在的位置是: 网站首页 > 程序设计  > Linux 

Linux程序性能调优之gprof和oprofile

2020年9月28日 19:18 1530人围观

简介Linux性能调优是个永恒的话题,几乎每一层都有分析工具,那么对于一个程序,我们怎么分析各个函数的耗时呢
对于后台程序来说,我们需要知道我们的程序耗时在哪里,哪个功能最耗时,一种做法是在每个函数的入口处加start_time,然后在函数返回时加上end_time,然后计算耗时。如果函数较少,这么做也可以,但是如果程序很复杂,显然这么做不显示。庆幸的是Linux提供了类似的工具,用很简单发方法就能统计出每个函数的耗时,这就是gprofoprofile
  • gprof主要用来查看用户级函数,这里的用户级函数包括自定义的函数以及和库函数,与之对应的是内核级函数,包括openreadwrite等,对于这些函数gprof无能为力了
  • oprofile

gprof

gprof的使用分4步骤

  1. 编写源文件
  2. gxx编译添加-g -pg参数
  3. 运行可执行文件,生成gmont.out
  4. gprof分析gmont.out文件

下面通过实例做个测试,自定义一个快排和冒泡排序,分析他们的耗时。

    #include <time.h> 
    #include <stdio.h> 
    #include <vector> 
    #include <iostream> 

    using namespace std; 

    int partion(vector<int> &arr, int low, int high) { 
        if (low >= high) return -1; 

        int key = arr[low]; 
        while (low < high) { 
            while (low < high && arr[high] >= key) high--; 
            arr[low] = arr[high]; 

            while (low < high && arr[low] <= key) low++; 
            arr[high] = arr[low]; 
        } 

        arr[low] = key; 
        return low; 
    } 

    void qsort(vector<int> &arr, int low, int high) { 
        if (low < high) { 
            int index = partion(arr, low, high); 
            qsort(arr, low, index - 1); 
            qsort(arr, index + 1, high); 
        } 
    } 

    void print_vector(vector<int> &arr) { 
        for (auto a : arr) { 
            cout << a << " "; 
        } 
        cout << endl; 
    } 

    void bubble_sort(vector<int> &arr) { 
        for (int i = 0; i < arr.size(); i++) { 
            for (int j = 0; j < arr.size() - i - 1; j++) { 
                if (arr[j] > arr[j+1]) { 
                    int t = arr[j]; 
                    arr[j] = arr[j+1]; 
                    arr[j+1] = t; 
                } 
            } 
        } 
    } 

    bool compare(vector<int> &arr1, vector<int> &arr2) { 
        if (arr1.size() != arr2.size()) return false; 

        for (int i = 0; i < arr1.size(); i++) { 
            if (arr1[i] != arr2[i]) { 
                return false; 
            } 
        } 

        return true; 
    } 

    int main() { 
        vector<int> arr1, arr2; 
        srandom(time(NULL)); 

        for (int i = 0; i < 10000; i++) { 
            arr1.push_back(rand() % 10000); 
        } 

        arr2 = arr1; 
        qsort(arr1, 0, arr1.size() - 1); 
        bubble_sort(arr2); 

        cout << compare(arr1, arr2) << endl; 
    } 

执行具体步骤:

  1. g++ -g -pg mysort.cpp -o mysort
  2. ./gmont.out
  3. gprof mysort -p

gprof v gmon.out -p 得到每个函数占用的执行时间 gprof mysort gmon.out -q 得到call graph,包含了每个函数的调用关系,调用次数,执行时间等信息。 gprof mysort gmon.out -A 得到一个带注释的“源代码清单”,它会注释源码,指出每个函数的执行次数。

分析结果如下:

结果按照耗时倒排,可以看到冒泡排序最耗时,占了整个程序的51.38%的时间。