记得原来做性能分析的时候,我会在代码的每个需要的地方打上时间戳,然后执行代码,然后再把时间戳相减,得出每个函数执行时间.这样就可以对整个模块的执行时间有了一个大体的概念.现在想想那个时候真的很傻.其实这部分工作.完全可以交给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 : 因为总是忘记这个工具的用法,所以写了这么一篇博客.没有什么技术含量.仅作为温习使用.