首页 > 解决方案 > 为什么我在分析器中看到 __scalbnf?

问题描述

我正在使用 分析一些 C++ 代码perf,我看到了这一点__scalbnf,并且__wrap_scalbnf占用了很大一部分运行时间。我查看了这些函数是什么,我最好的猜测是我通过调用来调用它们std::exp。但是,我希望能够确认这一点。有没有地方我可以看到实现 std::exp 的 C++ 代码来确认这一点?或者对我(C++ 业余爱好者)来说,开始深入研究并了解正在发生的事情的最佳方式是什么?

谢谢你。

标签: c++perfexp

解决方案


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

如果一个函数有多个调用者,那么第一个命中可能不是来自您正在分析的“热”函数。

要真正弄清楚哪个更高层函数(包括它的子函数)占用了大量时间,请参阅linux perf: how to interpret and findhotspots。自上而下的分析可以找到昂贵的函数,这些函数在调用其他函数时完成所有工作,即使这些其他函数也有“无辜”的调用者。(例如memcpy,被大量使用并且通常是不可避免的,但是您想要找到的是使用它太多并且可以更好地优化的调用者。或者根本不调用。)


顺便说一句,是的 glibc 的数学库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,使用 x87fscale指令进行 80 位浮点数。但只有 i386 asm 文件用于其他大小.和IA-64(安腾),但不是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(这是 for float,不是double。我忘记了是否有双版本的 SO 答案)。

还相关:在 AVX2 中高效实现 log2(__m256d)


推荐阅读