linux下的性能分析

记得原来做性能分析的时候,我会在代码的每个需要的地方打上时间戳,然后执行代码,然后再把时间戳相减,得出每个函数执行时间.这样就可以对整个模块的执行时间有了一个大体的概念.现在想想那个时候真的很傻.其实这部分工作.完全可以交给oprofile系列工具来完成.

先了解一下什么是oprofile.他是一系列工具的集合,是内核支持的性能分析工具.具体的工作模式我没有去深究,我只是一个用户.

oprofile包括以下几个工具:

注意这个工具需要以root权限执行.并且在执行前需要输入cat 0  > /proc/sys/kernel/nmi_watchdog.

opreport : 以粒度为函数级别输出评测结果

opannotate : 粒度为代码级别的评测结果.

op_help : 帮助信息.

对于这个工具,我掌握的内容并不是很多.接下来仅就一段测试程序做一个简单的分析:

首先是示例代码:

file.cpp

/******************************************************************************
 ** Coypright(C) 2014-2024 () technology Co., Ltd
 **
 ** 文件名 : file.cpp
 ** 版本号 : 1.0
 ** 描  述 : 
 ** 作  者 : cp3alai
 ** 日  期 : 2015.07.06
 ******************************************************************************/

#include "file.h"
#include <cstring>

CFILE::CFILE()
{
    m_file = NULL;
    m_filename = "";
}

CFILE::CFILE(CFILE &cFile)
{
    m_filename = cFile.m_filename;
    m_file = fopen(m_filename.c_str(), "r+w");
}

CFILE::CFILE(string &str, string &mode)
{
    m_filename = str;
    m_file = fopen(m_filename.c_str(), mode.c_str());
}

CFILE::~CFILE()
{
    if (NULL != m_file)
    {
        fclose(m_file);
        m_file = NULL;
    }
}

CFILE & CFILE::operator =(CFILE &cFile)
{
    this->m_filename = cFile.m_filename;
    this->m_file = fopen(m_filename.c_str(), "r+w");

    return *this;
}

void CFILE::operator >>(string &str)
{
    rewind(m_file);
    char buf[2048];
    
    memset(buf, 0, sizeof(buf));
    fread(buf, sizeof(buf) - 1, sizeof(char), m_file);

    str = buf;
}

void CFILE::operator <<(string &str)
{
    if (NULL == m_file)
    {
        perror("there is an error");
        return ;
    }

    fwrite(str.c_str(), sizeof(char), str.length(), m_file);
}
file.h

/******************************************************************************
 ** Coypright(C) 2014-2024 () technology Co., Ltd
 **
 ** 文件名 : file.h
 ** 版本号 : 1.0
 ** 描  述 : 
 ** 作  者 : cp3alai
 ** 日  期 : 2015.07.06
 ******************************************************************************/

#include <iostream>
#include <string>
#include <sstream>
#include <cstdio>

using namespace std;

class CFILE 
{
public:
    CFILE();
    CFILE(CFILE &cFile);
    CFILE(string &str, string &mode);
    ~CFILE();

    CFILE & operator = (CFILE &cFile);
    void operator >>(string &);
    void operator <<(string &);

private:
    FILE *m_file;
    string m_filename;
};
main.cpp

/******************************************************************************
 ** Coypright(C) 2014-2024 () technology Co., Ltd
 **
 ** 文件名 : main.cpp
 ** 版本号 : 1.0
 ** 描  述 : 
 ** 作  者 : cp3alai
 ** 日  期 : 2015.07.06
 ******************************************************************************/

#include "file.h"

int main(int argc, char **argv)
{
    for (;;)
    {
        string str = "alai.txt";
        string mode = "r+w";

        CFILE cFile(str, mode);
        cFile<<str;

        string out;
        cFile>>out;
    }
    return 0;
}

顺便温习了一下运算符重载.

接下来编译,需要用-g选项.不然opannotate不能正确执行.

过程如下:

首先启动opcontrol进行采样:


然后运行程序,主要需要运行一段时间,不然如果时间不够,可能无法输出正确的结果.

可以看到目前最大的开销集中于>>运算符重载.接下来是main.

我们再看看代码级别的性能:

限于篇幅,仅截取了一段代码.

以上就是opcontrol的一些基本用法.

PS : 因为总是忘记这个工具的用法,所以写了这么一篇博客.没有什么技术含量.仅作为温习使用.

相关文章
相关标签/搜索