Linux代码性能检测利器(二)--OProfile之代码分析示例
2017-04-18 16:45
519 查看
/Uploads/Images/Content/201911/04/7df1ca56f70e3127c0ea9e00986f70f2
对于做应用级别(相对内核开发)的开发,如果只想快速找到代码性能瓶颈而对OProfile的工作原理不感兴趣,只看该示例应该就足够了。
假如我们的代码文件是/home/leo/oprofile_test/main.cpp,内容是:
[cpp]
view plain
copy
#include <stdio.h>
#include <unistd.h>
#include <string.h>
class FileOp
{
public:
FileOp(char *file)
{
strcpy(m_fileName, file);
m_buff = new char[1024];
memset(m_buff, 0, 1024);
}
~FileOp()
{
delete []m_buff;
m_buff = NULL;
}
void DoWork()
{
FILE *fp = fopen(m_fileName, "r");
if(!fp)
{
return;
}
int count = 0;
int i = 0;
while(!feof(fp))
{
fgets(m_buff, 1023, fp);
count = strlen(m_buff);
usleep(100);
fprintf(stderr, "The %ld has %ld characters!\n", ++i, count);
}
fclose(fp);
}
private:
char m_fileName[1024];
char *m_buff;
};
int main(int argc, char **argv)
{
if(argc != 2)
{
return -1;
}
FileOp op(argv[1]);
op.DoWork();
return 0;
}
这段程序读取一个从命令行传递过来的一个文件,打印出每一行的字符数(这段代码是在64位机器上运行的)。
a) 使用“g++ -g main.cpp”将源代码编译成可执行程序
b) 使用“opcontrol --init”进行分析器初始化(启动分析器驱动模块)
c) 使用“opcontrol --setup --image=/home/leo/oprofile_test/a.out
--event=CPU_CLK_UNHALTED:6000:0”和“opcontrol --no-vmlinux”设置分析器,如下图所示:
d) 使用“opcontrol
--start”启动分析器
e) 运行程序,比如:“./a.out /var/log/messages.1”
运行完成后,使用下面的命令获取分析结果。
a) 运行“opcontrol --dump”将采样数据送入分析器中
b) 运行“opreport -l”查看函数级的分析结果,如下图所示:
由图中可以看到FileOp::DoWork的采样百分比占到了99.0909%,说明大部分的CPU时间都是在此函数中。
c) 运行“opannotate --source”查看代码级别的分析结果,如下图所示:
上图只是截取了关键的部分输出,从这个输出可以看到strlen这行占到了77%(红色矩形中数字768表示在分析采样过程中改行采样数量为768,即每次设置的事件发生时查看运行所在的代码位置,发现一次就对改行的采样数加1,。77.5758代表改行采样数占所有采样数的77.5758%),说明这段代码的运行效率很低,找到了性能瓶颈,接下来的工作就是找函数替换strlen啦!(strlen的效率实在很低,尤其是当字符串很长的时候)
OK,到此分析结果已经出来了,不过对于工程很大的情况,opreport和opannotate的输出很多,这时候把分析结果导出到文件中就比较容易查看了,对于opreport,可以使用“opreport
-l -o ./analysis.log”来讲分析结果输出到文件中,如下图所示:
而对于opannotate来讲,可以使用“opannotate
--source --output-dir=/tmp/”来讲分析结果对应到相应的源代码文件中,如下图所示:
上面的命令的意思是将相应的打了标注的源代码文件放在“/tmp/”目录下,在该目录下,会根据源代码的文件结构生成相对应的文件结果,如图,在“/tmp/”目录下生成了“home/leo/oprofile_test”目录,与源代码的目录一致,而“main.cpp”就在该目录下,打开该目录下的“main.cpp”就可以查看每句代码对应的采样数据以及资源占用百分比了。
用完了分析器,使用命令“opcontrol --stop”停止采样,命令“opcontrol --reset”清除当前会话中的采样数据,命令“opcontrol --shutdown”关闭分析器内核模块,“opcontrol --stop” 和命令“opcontrol --reset”是非常有必要的,因为不进行这两步下次在进行分析时就会受到这次结果的影响。
对于做应用级别(相对内核开发)的开发,如果只想快速找到代码性能瓶颈而对OProfile的工作原理不感兴趣,只看该示例应该就足够了。
假如我们的代码文件是/home/leo/oprofile_test/main.cpp,内容是:
[cpp]
view plain
copy
#include <stdio.h>
#include <unistd.h>
#include <string.h>
class FileOp
{
public:
FileOp(char *file)
{
strcpy(m_fileName, file);
m_buff = new char[1024];
memset(m_buff, 0, 1024);
}
~FileOp()
{
delete []m_buff;
m_buff = NULL;
}
void DoWork()
{
FILE *fp = fopen(m_fileName, "r");
if(!fp)
{
return;
}
int count = 0;
int i = 0;
while(!feof(fp))
{
fgets(m_buff, 1023, fp);
count = strlen(m_buff);
usleep(100);
fprintf(stderr, "The %ld has %ld characters!\n", ++i, count);
}
fclose(fp);
}
private:
char m_fileName[1024];
char *m_buff;
};
int main(int argc, char **argv)
{
if(argc != 2)
{
return -1;
}
FileOp op(argv[1]);
op.DoWork();
return 0;
}
这段程序读取一个从命令行传递过来的一个文件,打印出每一行的字符数(这段代码是在64位机器上运行的)。
a) 使用“g++ -g main.cpp”将源代码编译成可执行程序
b) 使用“opcontrol --init”进行分析器初始化(启动分析器驱动模块)
c) 使用“opcontrol --setup --image=/home/leo/oprofile_test/a.out
--event=CPU_CLK_UNHALTED:6000:0”和“opcontrol --no-vmlinux”设置分析器,如下图所示:
d) 使用“opcontrol
--start”启动分析器
e) 运行程序,比如:“./a.out /var/log/messages.1”
运行完成后,使用下面的命令获取分析结果。
a) 运行“opcontrol --dump”将采样数据送入分析器中
b) 运行“opreport -l”查看函数级的分析结果,如下图所示:
由图中可以看到FileOp::DoWork的采样百分比占到了99.0909%,说明大部分的CPU时间都是在此函数中。
c) 运行“opannotate --source”查看代码级别的分析结果,如下图所示:
上图只是截取了关键的部分输出,从这个输出可以看到strlen这行占到了77%(红色矩形中数字768表示在分析采样过程中改行采样数量为768,即每次设置的事件发生时查看运行所在的代码位置,发现一次就对改行的采样数加1,。77.5758代表改行采样数占所有采样数的77.5758%),说明这段代码的运行效率很低,找到了性能瓶颈,接下来的工作就是找函数替换strlen啦!(strlen的效率实在很低,尤其是当字符串很长的时候)
OK,到此分析结果已经出来了,不过对于工程很大的情况,opreport和opannotate的输出很多,这时候把分析结果导出到文件中就比较容易查看了,对于opreport,可以使用“opreport
-l -o ./analysis.log”来讲分析结果输出到文件中,如下图所示:
而对于opannotate来讲,可以使用“opannotate
--source --output-dir=/tmp/”来讲分析结果对应到相应的源代码文件中,如下图所示:
上面的命令的意思是将相应的打了标注的源代码文件放在“/tmp/”目录下,在该目录下,会根据源代码的文件结构生成相对应的文件结果,如图,在“/tmp/”目录下生成了“home/leo/oprofile_test”目录,与源代码的目录一致,而“main.cpp”就在该目录下,打开该目录下的“main.cpp”就可以查看每句代码对应的采样数据以及资源占用百分比了。
用完了分析器,使用命令“opcontrol --stop”停止采样,命令“opcontrol --reset”清除当前会话中的采样数据,命令“opcontrol --shutdown”关闭分析器内核模块,“opcontrol --stop” 和命令“opcontrol --reset”是非常有必要的,因为不进行这两步下次在进行分析时就会受到这次结果的影响。
相关文章推荐
- Linux代码性能检测利器(二)--OProfile之代码分析示例
- Linux代码性能检测利器(五)-OProfile分析结果误区
- Linux代码性能检测利器(四)- 获取分析结果
- Linux代码性能检测利器
- Linux代码性能检测利器(三)-控制分析器opcontrol使用说明
- Linux代码性能检测利器(一)--OProfile概述
- 和菜鸟一起学linux之linux性能分析工具oprofile移植
- Linux下系统性能检测利器dstat
- <2012 12 02> linux下利用valgrind工具进行内存泄露检测和性能分析
- linux下利用valgrind工具进行内存泄露检测和性能分析
- 怎样使用gprof和oprofile来分析linux程序的性能
- Linux下利用Valgrind工具进行内存泄露检测和性能分析
- Linux下运行OProfile进行系统性能分析
- 怎样使用gprof和oprofile来分析 linux程序的性能(每个函数的调用次数与耗时)
- Linux下利用Valgrind工具进行内存泄露检测和性能分析
- Linux下利用Valgrind工具进行内存泄露检测和性能分析
- gprof && oprofile 分析linux程序性能瓶颈
- 怎样使用gprof和oprofile来分析linux程序的性能
- Linux 平台上的 Oprofile 性能分析工具
- linux下利用valgrind工具进行内存泄露检测和性能分析