性能测试:oprofile的学习使用

时间:2023-01-31 21:13:48

一、oprofile简介

Oprofile是linux上的性能监测工具,有人说是性能测试的神器。通过CPU硬件提供的性能计数器对事件进行采样,从代码层面分析程序的性能消耗情况,找出程序性能的问题点。

oProfile是Linux平台上的一个功能强大的性能分析工具,支持两种采样(sampling)方式:基于事件的采样(eventbased)和基于时间的采样(timebased)。
基于事件的采样是oProfile只记录特定事件(比如L2 cache miss)的发生次数,当达到用户设定的定值时oProfile就记录一下(采一个样)。这种方式需要CPU内部有性能计数器(performace counter)。
基于时间的采样是oProfile借助OS时钟中断的机制,每个时钟中断oProfile都会记录一次(采一次样),引入此种采样方式的目的在于提供对没有性能计数器的CPU的支持,其精度相对于基于事件的采样要低。因为要借助OS时钟中断的支持,对禁用中断的代码oProfile不能对其进行分析。

oProfile在Linux上分两部分,一个是内核模块(oprofile.ko),一个为用户空间的守护进程(oprofiled)。前者负责访问性能计数器或者注册基于时间采样的函数(使用register_timer_hook注册之,使时钟中断处理程序最后执行profile_tick时可以访问之),并采样置于内核的缓冲区内。后者在后台运行,负责从内核空间收集数据,写入文件。

二、原理

CPU都提供一个性能计数器的东西(performance counter),大致的原理就是程序可以注册告诉CPU对什么event感兴趣(比如CPU_CYCLE,CPU经历了一次时钟周期),然后CPU在执行了相应的操作后,就会在性能计数器上加1,这样程序就可以取出。所以,使用OProfile来定位CPU使用率的问题,就变成了让oprofile收集 程序运行过程中哪个可执行程序(或是so)中的哪个function,消耗的CPU CYCLE最多。

也就是说我们可以通过收集数据知道哪个程序的哪个函数消耗的cpu时间占比。这种测试方法结果更符合实际情况,属于代码层面的测试。

三、Ubuntu16.04下安装oprofile

(一)、准备工作

Popt下载:http://www.linuxfromscratch.org/blfs/view/svn/general/popt.html

binutils下载:http://ftp.gnu.org/gnu/binutils/?C=M;O=D

oprofile下载:在官网上下载,我下载的版本为oprofile-1.3.0.tar.gz

(二)、安装

直接安装:

/workdisk/software/# apt install oprofile

可以先用直接安装方法,如果错误再往下看。

/workdisk/software/# apt install popt-devel
/workdisk/software/# apt install binutils
/workdisk/software/# apt install binutils-devel

还是不行的话,就下载后源码安装:

1、popt安装

 解压
root@ranxf-TEST:/workdisk/software/popt-1.16# ./configure --prefix=/usr
make
make install

2、binutils安装

 解压tar -xvf binutils-2.32.tar.xz
cd binutils-2.32
root@ranxf-TEST:/workdisk/software/binutils-2.32# ./configure --with-sysroots
root@ranxf-TEST:/workdisk/software/binutils-2.32# make clean
root@ranxf-TEST:/workdisk/software/binutils-2.32# make
root@ranxf-TEST:/workdisk/software/binutils-2.32# make install

3、oprofile安装

oprofile安装
/workdisk/software/oprofile-1.3.0# ./configure --prefix=/workdisk/oprofile/
/workdisk/software/oprofile-1.3.0# make
/workdisk/software/oprofile-1.3.0# make install

如果按照以上安装方法,出现如下错误
Configuration error: Iberty library not
found 按照以下顺序重新安装解决
/workdisk/software/oprofile-1.3.0# apt-file update
/workdisk/software/oprofile-1.3.0# apt-get install apt-file
/workdisk/software/oprofile-1.3.0# apt-get install libiberty-dev /workdisk/software/oprofile-1.3.0# ./configure --prefix=/workdisk/oprofile/
/workdisk/software/oprofile-1.3.0# make
/workdisk/software/oprofile-1.3.0# make install

Configuration error: Iberty library not found参见该链接:Configuration error: Iberty library not found

安装过程也可以直接写成:./configure make & make install

大型软件编译过程可以在make前面加一条make clean对先前编译结果进行清除

三、验证oprofile是否安装成功

 https://oprofile.sourceforge.io/news/官网显示:1.0.0之后版本的一个重大变化是删除了基于传统opcontrol的分析器。自从operf首次引入版本0.9.8以来,旧版概要分析工具已被弃用。

operf -version
operf: oprofile 1.1.0 compiled on Aug 10 2016 19:53:16

四、oprofile的使用

使用operf进行分析可以精确定位分析(即单个过程或系统范围)。使用operf,无需初始设置 - 只需使用您需要的选项调用operf ; 然后运行OProfile后处理工具。该operf语法如下:

operf [options] [--system-wide | --pid = <PID> | [command [args]]]

典型用法可能如下所示:

operf ./my_test_program my_arg

./my_test_program完成时(或按Ctrl-C),停止,你就可以使用opreport或其他OProfile的后处理工具。

默认情况下,operf将样本数据存储在其中<cur_dir>/oprofile_data/samples/current,而opreport和其他后处理工具将首先查找该位置的配置文件数据,除非您通过该--session-dir选项到指定位置。

operf:
operf -g -p 1525
如果多个线程区别较大,可加上 -t root@ranxf-TEST:/workdisk/oprofile# operf -g -p 1525
operf: Press Ctl-c or 'kill -SIGINT 8288' to stop profiling
operf: Profiler started
^C
WARNING: Lost samples detected! See /workdisk/oprofile/oprofile_data/samples/operf.log for details.(警告:检测到丢失的样本!有关详细信息,请参阅/workdisk/oprofile/oprofile_data/samples/operf.log。)
Lowering the sampling rate may reduce or eliminate lost samples.
See the '--events' option description in the operf man page for help. Profiling done.
opreport:
opreport -l | more
opreport -c -% -f -g -s sample | more opannotate:
opannotate -s

五、常见问题

找不到样本:

使用operf,请确保从收集配置文件的目录运行OProfile后处理工具(例如,opreport,opannotate)。或者,您可以使用--session-dir选项指定样本数据的位置。

调用后处理工具时图像名称(即应用程序名称)的错误规范是此错误消息的常见原因。如果您使用operf来分析单个应用程序,则无需在调用结束时附加图像名称,因为仅为给定的应用程序收集样本。

官方文档

 Following is a description of the operf options.

 command [args]

     The command or application to be profiled. The [args] are the input arguments that the command or application requires. Either command, --pid or --system-wide is required, but cannot be used simultaneously.
--pid / -p [PID] This option enables operf to profile a running application. PID should be the process ID of the process you wish to profile. When finished profiling (e.g., when the profiled process ends), press Ctrl-c to stop operf.
--system-wide / -s This option is for performing a system-wide profile. You must have root authority to run operf in this mode. When finished profiling, Ctrl-C to stop operf. If you run operf --system-wide as a background job (i.e., with the &), you must stop it in a controlled manner in order to process the profile data it has collected. Use kill -SIGINT <operf-PID> for this purpose. It is recommended that when running operf with this option, your current working directory should be /root or a subdirectory of /root to avoid storing sample data files in locations accessible by regular users.
--vmlinux / k [vmlinux_path] A vmlinux file that matches the running kernel that has symbol and/or debuginfo. Kernel samples will be attributed to this binary, allowing post-processing tools (like opreport) to attribute samples to the appropriate kernel symbols. If this option is not specified, the file /proc/kallsyms is used to obtain kernel symbol addresses correponding to sample addresses. However, the setting of /proc/sys/kernel/kptr_restrict may restrict a non-root user's access to /proc/kallsyms, in which case, all kernel samples are attributed to a pseudo binary named "no-vmlinux".
--callgraph / -g This option enables the callgraph to be saved during profiling. NOTE: The full callchain is recorded, so there is no depth limit.
--append / -a By default, operf moves old profile data from <session_dir>/samples/current to <session_dir>/samples/previous. If a 'previous' profile already existed, it will be replaced. If the --append option is passed, old profile data in 'current' is left in place and new profile data will be added to it, and the 'previous' profile (if one existed) will remain untouched. To access the 'previous' profile, simply add a session specification to the normal invocation of oprofile post-processing tools; for example: opreport session:previous --events / -e [event1[,event2[,...]]] This option is for passing a comma-separated list of event specifications for profiling. Each event spec is of the form: name:count[:unitmask[:kernel[:user]]] When no event specification is given, the default event for the running processor type will be used for profiling. Use ophelp to list the available events for your processor type.
--separate-thread / -t This option categorizes samples by thread group ID (tgid) and thread ID (tid). The --separate-thread option is useful for seeing per-thread samples in multi-threaded applications. When used in conjuction with the --system-wide option, --separate-thread is also useful for seeing per-process (i.e., per-thread group) samples for the case where multiple processes are executing the same program during a profiling run.
--separate-cpu / -c This option categorizes samples by cpu.
--session-dir / -d [path] This option specifies the session directory to hold the sample data. If not specified, the data is saved in the oprofile_data directory on the current path.
---lazy-conversion / -l Use this option to reduce the overhead of operf during profiling. Normally, profile data received from the kernel is converted to OProfile format during profiling time. This is typically not an issue when profiling a single application. But when using the --system-wide option, this on-the-fly conversion process can cause noticeable overhead, particularly on busy multi-processor systems. The --lazy-conversion option directs operf to wait until profiling is completed to do the conversion of profile data.
--verbose / -V [level] A comma-separated list of debugging control values used to increase the verbosity of the output. Valid values are: debug, record, convert, misc, sfile, arcs, and the special value, 'all'.
--version -v Show operf version.
--help / -h Show a help message
54 Options for opreport

--accumulated / -a Accumulate sample and percentage counts in the symbol list.
--callgraph / -c Show callgraph information.
--debug-info / -g Show source file and line for each symbol.
--demangle / -D none|normal|smart none: no demangling. normal: use default demangler (default) smart: use pattern-matching to make C++ symbol demangling more readable.
--details / -d Show per-instruction details for all selected symbols. Note that, for binaries without symbol information, the VMA values shown are raw file offsets for the image binary.
--exclude-dependent / -x Do not include application-specific images for libraries, kernel modules and the kernel..
--exclude-symbols / -e [symbols] Exclude all the symbols in the given comma-separated list.
--global-percent / -% Make all percentages relative to the whole profile.
--help / -? / --usage Show help message.
--image-path / -p [paths] Comma-separated list of additional paths to search for binaries. This is needed to find kernel modules.
--root / -R [path] A path to a filesystem to search for additional binaries.
--include-symbols / -i [symbols] Only include symbols in the given comma-separated list.
--long-filenames / -f Output full paths instead of basenames.
--merge / -m [lib,cpu,tid,tgid,unitmask,all] Merge any profiles separated in a --separate session.
--no-header Don't output a header detailing profiling parameters.
--output-file / -o [file] Output to the given file instead of stdout.
--reverse-sort / -r Reverse the sort from the default.
--session-dir=dir_path Use sample database from the specified directory dir_path instead of the default location. If this option is not specified, then opreport will search for samples in <cur_dir>/oprofile_data first. If that directory does not exist, the standard session-dir of /var/lib/oprofile is used as the session directory.
--show-address / -w Show the VMA address of each symbol (off by default).
--sort / -s [vma,sample,symbol,debug,image] Sort the list of symbols by, respectively, symbol address, number of samples, symbol name, debug filename and line number, binary image filename.
--symbols / -l List per-symbol information instead of a binary image summary.
--threshold / -t [percentage] Only output data for symbols that have more than the given percentage of total samples. For profiles using multiple events, if the threshold is reached for any event, then all sample data for the symbol is shown.
--verbose / -V [options] Give verbose debugging output.
--version / -v Show version.
--xml / -X Generate XML output. Usage of opannotate

--assembly / -a Output annotated assembly. If this is combined with --source, then mixed source / assembly annotations are output.
--base-dirs / -b [paths]/ Comma-separated list of path prefixes. This can be used to point OProfile to a different location for source files when the debug information specifies an absolute path on your system for the source that does not exist. The prefix is stripped from the debug source file paths, then searched in the search dirs specified by --search-dirs.
--demangle / -D none|normal|smart none: no demangling. normal: use default demangler (default) smart: use pattern-matching to make C++ symbol demangling more readable.
--exclude-dependent / -x Do not include application-specific images for libraries, kernel modules and the kernel.
--exclude-file [files] Exclude all files in the given comma-separated list of glob patterns. This option is supported solely with the --source option. It can be used to filter out source files in the output using the following types of specifications: filenames (basename -- i.e., no path)
filename glob specifications (all files whose base filename matches the given pattern)
directory segments (all source files located in the specified directory; e.g. "libio")
directory segment glob specifications (e.g., "libi*") --exclude-symbols / -e [symbols] Exclude all the symbols in the given comma-separated list.
--help / -? / --usage Show help message.
--image-path / -p [paths] Comma-separated list of additional paths to search for binaries. This is needed to find kernel modules.
--root / -R [path] A path to a filesystem to search for additional binaries.
--include-file [files] Only include files in the given comma-separated list of glob patterns. The same rules apply for this option as for the --exclude-file option.
--include-symbols / -i [symbols] Only include symbols in the given comma-separated list.
--objdump-params [params] Pass the given parameters as extra values when calling objdump. If more than one option is to be passed to objdump, the parameters must be enclosed in a quoted string. An example of where this option is useful is when your toolchain does not automatically recognize instructions that are specific to your processor. For example, on IBM POWER7/RHEL 6, objdump must be told that a binary file may have POWER7-specific instructions. The opannotate option to show the POWER7-specific instructions is: --objdump-params=-Mpower7 The opannotate option to show the POWER7-specific instructions, the source code (--source) and the line numbers (-l) would be: --objdump-params="-Mpower7 -l --source" --output-dir / -o [dir] Output directory. This makes opannotate output one annotated file for each source file. This option can't be used in conjunction with --assembly.
--search-dirs / -d [paths] Comma-separated list of paths to search for source files. This is useful to find source files when the debug information only contains relative paths.
--source / -s Output annotated source. This requires debugging information to be available for the binaries.
--session-dir=dir_path Use sample database from the specified directory dir_path instead of the default location. If this option is not specified, then opannotate will search for samples in <cur_dir>/oprofile_data first. If that directory does not exist, the standard session-dir of /var/lib/oprofile is used as the session directory.
--threshold / -t [percentage] For annotated assembly, only output data for symbols that have more than the given percentage of total samples. For profiles using multiple events, if the threshold is reached for any event, then all sample data for the symbol is shown. For annotated source, only output data for source files that have more than the given percentage of total samples. For profiles using multiple events, if the threshold is reached for any event, then all sample data for the source file is shown.
--verbose / -V [options] Give verbose debugging output.
--version / -v Show version.

参考文章

  使用oprofile-1.1.0:https://blog.csdn.net/spche/article/details/72831596

  官网OProfile manual:https://oprofile.sourceforge.io/doc/index.html