为什么我在探查器中看到__scalbnf?

时间:2018-07-02 15:38:18

标签: c++ perf exp

我正在使用perf对一些C ++代码进行概要分析,并且发现__scalbnf__wrap_scalbnf占用了大量的运行时间。我查看了这些功能是什么,我最好的猜测是我通过调用std::exp来调用它们。但是,我希望能够确认这一点。在哪里可以看到C ++代码实现std :: exp来确认这一点?还是对我(C ++业余爱好者)来说,开始深入研究并了解正在发生的事情的最佳方法是什么?

谢谢。

2 个答案:

答案 0 :(得分:1)

要确认std::exp__scalbnf__wrap_scalbnf的原因,您可以用以下任一方法替换std::exp调用:

  • 返回输入值的身份函数
  • 或通过其他exp实现(例如fm_exp,找到here

然后,如果您仍然在探查器输出中看到__scalbnf__wrap_scalbnf,则表明它不是来自std :: exp。

答案 1 :(得分:1)

__scalbn上设置一个断点。运行程序。查看回溯(在GDB中,bt。调用树将显示exp()__scalbn的父函数。

如果一个函数有多个调用者,则第一个匹配项可能不是您正在分析的“热门”函数。

要真正弄清楚哪个上级功能(包括其子级)是造成大量时间的原因,请参见linux perf: how to interpret and find hotspots 。自上而下的概要分析可以找到昂贵的函数,这些函数可以在对其他函数的调用中完成所有工作,即使这些其他函数也具有“无辜的”调用者。 (例如memcpy经常被使用并且经常不可避免,但是您想要找到的调用者使用它过多并且可以进行更好的优化。或者根本不被调用。)


顺便说一句,是的,glibc的math lib exp()实现确实在内部使用__scalbn。我不确定实现的糟糕程度,但是我看不到x86-64的asm版本,只有这个纯C版本。 https://code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c.html。 (对于__scalbnl(long double),有https://code.woboq.org/userspace/glibc/sysdeps/x86_64/fpu/s_scalbnl.S.html,使用x87 fscale指令进行80位浮点运算。但是只有其他大小的i386 asm文件。IA-64(Itanium),但是不是x86-64)。

glibc确实有一些矢量化的EXP代码,例如SSE4 SVML版本https://code.woboq.org/userspace/glibc/sysdeps/x86_64/fpu/multiarch/svml_d_exp2_core_sse4.S.html#_ZGVbN2v_exp_sse4


如果您想要性能更高的exp()而又没有完美的准确性,请参阅Fastest Implementation of Exponential Function Using AVX(这是针对float的,而不是double的。我忘记了是否有SO答案是双版本)。

也相关:Efficient implementation of log2(__m256d) in AVX2