程序性能分析工具perf

简介

https://zhuanlan.zhihu.com/p/141694060

使用方法

编写test_perf.c程序如下

#include<stdio.h>
#include<stdlib.h>

void test_perf(){
    int row = 10, col = 100;
    double* arr = (double*)malloc(sizeof(double) * row * col);
    for(int i = 0; i < row; i++){
        for(int j = 0; j < col; j++){
            arr[i * col + j] = 1;
            arr[i * col + j] /= 10;
        }
    }
}

int main(){
    test_perf();
    return 0;
}

CMakeList.txt文件

cmake_minimum_required(VERSION 2.8)

project(test C)
set(CMAKE_C_STANDARD 99)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -o0")

add_executable(test test_perf.c)
target_link_libraries(test m)

编译生成test可执行文件

mkdir build
cd build
cmake ..
make

使用三板斧
运行程序生成perf.data

perf record ./test

查看perf.data文件

perf report

overhead一列为占时百分比,command为执行的命令(./test) Shared Object为目标对象,**.so为调用的动态库,Symbol为函数名或函数地址。

Overhead  Command  Shared Object     Symbol
  94.95%  test     libc-2.17.so      [.] _dl_addr                                                                      ▒   4.88%  test     [unknown]         [k] 0xffff000010083378                                                            ▒
   0.18%  test     ld-2.17.so        [.] _dl_start                                                                     ▒
   0.00%  test     ld-2.17.so        [.] _start                                                                        ▒
   0.00%  test     [unknown]         [k] 0xffff0000100814d8  

只有test命令可以看到与程序相关的东西,其它的一般是看不出来什么东西的。。。
more detail
没有关于函数void test_perf()的原因是采样频率不够
增大采样频率再查看

 perf record -F 100000 ./test
 perf report
 Overhead  Command  Shared Object     Symbol
  26.50%  test     libc-2.17.so      [.] _dl_addr
  20.68%  test     ld-2.17.so        [.] _dl_relocate_object
  11.06%  test     ld-2.17.so        [.] _dl_lookup_symbol_x
   7.09%  test     ld-2.17.so        [.] strcmp
   7.05%  test     test              [.] test_perf
   6.68%  test     ld-2.17.so        [.] do_lookup_x
   3.05%  test     ld-2.17.so        [.] mempcpy
   2.86%  test     ld-2.17.so        [.] _dl_load_cache_lookup
   2.69%  test     [unknown]         [k] 0xffff000010095e90
   2.68%  test     ld-2.17.so        [.] strlen
   2.42%  test     ld-2.17.so        [.] _dl_check_map_versions
   2.18%  test     ld-2.17.so        [.] memset
   2.04%  test     ld-2.17.so        [.] _dl_important_hwcaps
   1.32%  test     [unknown]         [k] 0xffff000010083378
   0.66%  test     ld-2.17.so        [.] _dl_next_ld_env_entry
   0.40%  test     ld-2.17.so        [.] _dl_start
   0.40%  test     ld-2.17.so        [.] _dl_sysdep_start
   0.23%  test     ld-2.17.so        [.] _wordcopy_fwd_aligned
   0.00%  test     ld-2.17.so        [.] _start
   0.00%  test     [unknown]         [k] 0xffff0000100814d8

在Shared Object中可以找到我们的可执行程序test,在Symbol中可以找到我们的函数test_perf,也是我们程序中唯一可以优化的地方(当然也可以替换更快的动态库.so)。
也可以更详细地查看汇编代码,按上下键移动到test_perf一行,按enter,选择第一行的Annotate test_perf ,按enter。

Annotate test_perf                                                                                                      Zoom into test thread                                                                                                  ▒
Zoom into test DSO (use the 'k' hotkey to zoom directly into the kernel)                                               ▒
Browse map details                                                                                                     ▒
Run scripts for samples of symbol [test_perf]                                                                          ▒
Run scripts for all samples                                                                                            ▒
Switch to another data file in PWD                                                                                     ▒Exit                                                                                                                   ▒

查看汇编

Percent│       mul   w1, w1, w0                                                                                        ▒
       │       ldr   w0, [x29,#40]                                                                                     ▒
       │       add   w0, w1, w0                                                                                        ▒
       │       sxtw  x0, w0                                                                                            ▒
       │       lsl   x0, x0, #3100.00 │       ldr   x1, [x29,#24]                                                                                     ▒
       │       add   x0, x1, x0                                                                                        ▒
       │       fmov  d0, #1.000000000000000000e+01                                                                     ▒
       │       fdiv  d0, d1, d0                                                                                        ▒
       │       str   d0, [x0]                                                                                          ▒
       │       ldr   w0, [x29,#40]                                                                                     ▒
       │       add   w0, w0, #0x1                                                                                      ▒
       │       str   w0, [x29,#40]                                                                                     ▒
       │ d0:   ldr   w1, [x29,#40]                                                                                     ▒
       │       ldr   w0, [x29,#32]                                                                                     ▒
       │       cmp   w1, w0                                                                                            ▒
       │     ↑ b.lt  40                                                                                               ▒
       │       ldr   w0, [x29,#44]
       │       add   w0, w0, #0x1                                                                                      ▒
       │       str   w0, [x29,#44]                                                                                     ▒
       │ ec:   ldr   w1, [x29,#44]                                                                                     ▒
       │       ldr   w0, [x29,#36]                                                                                     ▒
       │       cmp   w1, w0                                                                                            ▒
       │     ↑ b.lt  38  

左侧表示站当前函数(Symbol)的百分比,找到100.00,可以对应上程序中的两个for循环。
汇编看起来太麻烦,编译选项中添加-g,就可以自动对应了。
找到我们的CMakeList.txt
改成如下格式

cmake_minimum_required(VERSION 2.8)

project(test C)
set(CMAKE_C_STANDARD 99)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -o0 -g")

add_executable(test test_perf.c)
target_link_libraries(test m)

编译,生成可执行文件

 perf record -F 100000 ./test
 perf report

找到test_perf的汇编代码

for(int j = 0; j < col; j++){ 
│  ldr   w0, [x29,#40]
│  add   w0, w0, #0x1 
│  str   w0, [x29,#40]
│  ldr   w1, [x29,#40]
│  ldr   w0, [x29,#32]
│  cmp   w1, w0  
└──b.lt  40

参考

https://zhuanlan.zhihu.com/p/141694060

### 回答1: perf是一个流行的系统级性能分析工具,它可以帮助用户监测系统资源的使用情况,找出程序的性能瓶颈,提高程序的运行效率。perf具有以下几个特点: 第一,perf可以监控CPU、内存、硬盘I/O、网络等系统资源的使用情况,通过分析这些数据,可以找到程序的瓶颈所在。 第二,perf支持多种测量模式,包括采样模式、跟踪模式、事件计数模式等,方便用户根据自己的需要进行性能分析。 第三,perf可以和其他一些工具结合使用,如火焰图、Callgrind等,可以更加直观地展示程序的性能瓶颈,便于用户找到问题。 第四,perf对于内核开发人员也十分有用,可以帮助他们在开发过程中找到内核的性能问题,优化内核代码。 总之,perf是一款功能强大的性能分析工具,可以帮助用户在开发过程中找到程序的性能问题,提高程序的运行效率。 ### 回答2: perf是一款开源的系统级性能分析工具,它可以帮助开发者实现对Linux系统的性能分析和优化。perf可以测量和记录CPU的使用率、缓存的效率、内存的占用、磁盘I/O的读写速度等关键性能指标。 perf具有很强的功能,如事件计数器、系统调用跟踪、板载性能监视器等。使用perf分析工具来优化代码是极为有效的,而且很容易实现。perf的操作简单易学,它使用命令行用户界面,可以轻松地探测出代码中的性能削弱点。 除此之外,perf还提供了分析结果保存、数据可视化和报告生成等功能,这些功能将有助于关键的性能指标的更好的整理和分析perf还支持监视多线程程序,可以帮助开发人员分析并发应用程序的性能瓶颈。 总的来说,perf是一款非常强大的系统级性能分析工具,它可以帮助开发人员进行更加高效、精确地性能分析。相比于其他分析工具perf的性能表现更加稳定,且支持多种类型的分析,因此成为了许多开发人员在Linux系统上进行性能测试和优化的首选工具之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值