当前位置: 首页 > 面试题库 >

性能启用拆解调用图

傅边浩
2023-03-14
问题内容

如何为perf调用图启用C ++分解?当我进入注释模式时,似乎在符号上取消了符号的修饰,但在主调用图中却没有。

示例代码(使用Google Benchmark):

#include <benchmark/benchmark.h>
#include <vector>

static __attribute__ ((noinline)) int my_really_big_function()
{
  for(size_t i = 0; i < 1000; ++i)
  {
    benchmark::DoNotOptimize(i % 5);
  }
  return 0;
}

static __attribute__ ((noinline)) void caller1()
{
  for(size_t i = 0; i < 1000; ++i)
  {
    benchmark::DoNotOptimize(my_really_big_function());
    benchmark::DoNotOptimize(i % 5);
  }
}

static __attribute__ ((noinline)) void myfun(benchmark::State& state)
{
  while(state.KeepRunning())
  {
    caller1();
  }
}

BENCHMARK(myfun);

BENCHMARK_MAIN();

构建命令:

clang++ main.cpp -o main -fno-omit-frame-pointer -O0 -lpthread -lbenchmark

性能命令:

perf record -g ./main
perf report -g 'graph,0.5,caller'

我也尝试过启用–demangle选项,但这似乎并不影响输出。

Callgraph缺少脱格符号:

Samples: 3K of event 'cycles', Event count (approx.): 2946754102
Children      Self  Command  Shared Object      Symbol
+   99.82%     0.00%  main     main               [.] _ZL5myfunRN9benchmark5StateE
+   99.82%     0.00%  main     main               [.] _ZN9benchmark12_GLOBAL__N_111RunInThreadEPKNS_8internal9Benchmark8InstanceEmiPNS0_11ThreadStatsE
+   99.82%     0.00%  main     main               [.] _ZN9benchmark22RunSpecifiedBenchmarksEPNS_17BenchmarkReporterE
+   99.82%     0.00%  main     main               [.] main
+   99.82%     0.00%  main     libc-2.21.so       [.] __libc_start_main
+   99.82%     0.00%  main     [unknown]          [.] 0x7fbe258d4c544155
+   99.75%     0.30%  main     main               [.] _ZL7caller1v
+   99.52%    99.46%  main     main               [.] _ZL22my_really_big_functionv

带注释的反汇编显示了已取消组合的调用:

       │
       │    0000000000404310 <caller1()>:
       │    _ZL7caller1v():
       │      push   %rbp
       │      mov    %rsp,%rbp
       |    $0x30,%rsp
       |   $0x0,-0x18(%rbp)
       │10:   cmpq   $0x3e8,-0x18(%rbp)
       │    ↓ jae    6f
       │    → callq  my_really_big_function()
       │      lea    -0x1c(%rbp),%rcx
       │      mov    %eax,-0x1c(%rbp)
 14.29 │      mov    %rcx,-0x10(%rbp)
       │      mov    -0x10(%rbp),%rcx
       │      lea    -0x28(%rbp),%rcx
       │      mov    $0x5,%eax
       │      mov    %eax,%edx
       │      mov    -0x18(%rbp),%rax
       │      xor    %esi,%esi
       │      mov    %rdx,-0x30(%rbp)
       │      mov    %esi,%edx
       │      mov    -0x30(%rbp),%rdi
       │      div    %rdi
 85.71 │      mov    %rdx,-0x28(%rbp)
       │      mov    %rcx,-0x8(%rbp)
       │      mov    -0x8(%rbp),%rcx
       │      mov    -0x18(%rbp),%rax
       │      add    $0x1,%rax
       │      mov    %rax,-0x18(%rbp)
       │    ↑ jmpq   10
       │6f:   add    $0x30,%rsp
       │      pop    %rbp
       │    ← retq

系统信息:

  • Ubuntu 15.04 64位
  • 英特尔i5-6600k
  • 性能3.19.8-ckt6
  • 铛3.6.0-2ubuntu1

问题答案:

我在Ubuntu
15.10上遇到了相同的问题,并且在这里找到了解决方案:https
:
//bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654


更新:也适用于Ubuntu 18.10

步骤如下:

sudo apt-get install libiberty-dev binutils-dev
mkdir ~/install
cd ~/install
# If the following apt-get doesn't work on your system,
# uncomment deb-src lines in your /etc/apt/sources.list,
# as suggested by @ctitze
# or you can download it manually from packages.ubuntu.com
# as @aleixrocks suggested in the comment below
apt-get source linux-tools-`uname -r`
sudo apt-get build-dep linux-tools-`uname -r`
cd linux-`uname -r | sed 's/-.*//'`/tools/perf
make

# now you should see the new "perf" executable here
./perf

还应该有一些方法来创建一个新的linux-tools-common软件包,以将其真正集成到您的系统中。现在,用您的新性能替代正式性能,只需设置PATH:

export PATH=~/install/linux-`uname -r | sed 's/-.*//'`/tools/perf:$PATH


 类似资料:
  • 问题内容: 我正在研究是否可以在python中实现简单的回调功能。我以为我可以为此使用weakref.WeakSet,但是显然我缺少了一些东西或被误解了。正如您在代码中看到的那样,我首先尝试使用“ ClassA”对象中的回调方法列表,但意识到这将使添加到回调列表中的对象保持活动状态。相反,我尝试使用weakref.WeakSet,但这也不起作用(至少不是这样)。最后四行代码中的注释说明了我想要发生

  • 问题内容: 我有这段代码在做Range Minimum Query 。当t = 100000时,i和j始终在每条输入行中更改,因此在Java 8u60中其执行时间约为12秒。 当我提取一个新方法以找到最小值时,执行时间快了4倍(约2.5秒)。 我一直认为方法调用很慢。但是这个例子却相反。Java 6也演示了这一点,但是在两种情况下(17秒和10秒)执行时间都慢得多。有人可以对此提供一些见识吗? 问

  • 我有一段代码在做最小范围查询。当t=100000时,i和j在每个输入行中总是发生变化,其在Java8u60中的执行时间约为12秒。 当我提取一个新方法来寻找最小值时,执行时间快了4倍(大约2.5秒)。 我一直认为方法调用很慢。但是这个例子显示了相反的情况。Java6也演示了这一点,但是两种情况下的执行时间都要慢得多(17秒和10秒)。有人能对此提供一些见解吗?

  • 显示或隐藏左上角的 性能监控 组件。在使用这个API之前,需要先在HTML页面的 <header> 部分引入stats.min.js <header>         <script src="stats.min.js"></script> </header> controller.enableStats(); controller.disableStats();

  • 我们有一个解析excel的应用程序(大约100k),对于excel中的每一行,我们将调用4个不同的REST调用[在不同的域中],返回的输出存储在REDIS实例中以供进一步处理 1) 如果有100k条记录,我们将进行100k*4个REST API并行调用(50个线程并行),一条记录需要30秒才能完成整个过程。这似乎减慢了我们的进程,因此是否有其他替代框架(在java相关技术中会很有帮助)可以用来加快

  • 问题内容: 这是我的应用程序中的当前代码: 在对应用程序进行性能分析时,我注意到用于拆分字符串的时间不可忽略。 我还了解到,实际上需要一个正则表达式,这对我来说毫无用处。 所以我的问题是, 我可以使用哪种替代方法来优化字符串拆分? 我见过,但是速度更快吗? (我会尝试并测试自己,但是对我的应用程序进行性能分析需要花费很多时间,因此,如果有人已经知道答案,那么可以节省一些时间) 问题答案: 如果您的