c++ - 为什么我在分析器中看到 __scalbnf?
问题描述
我正在使用 分析一些 C++ 代码perf
,我看到了这一点__scalbnf
,并且__wrap_scalbnf
占用了很大一部分运行时间。我查看了这些函数是什么,我最好的猜测是我通过调用来调用它们std::exp
。但是,我希望能够确认这一点。有没有地方我可以看到实现 std::exp 的 C++ 代码来确认这一点?或者对我(C++ 业余爱好者)来说,开始深入研究并了解正在发生的事情的最佳方式是什么?
谢谢你。
解决方案
在 上设置断点__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 答案)。
推荐阅读
- html - 引导轮播滑块无法正常工作
- node.js - IntelliJ:为什么 Node.js 启动器在调试模式下会崩溃?
- dart - 我可以从 HttpClientResponse 返回 json 列表吗
- node.js - 带有“$regex”的“InvalidPipelineOperator”
- matlab - 如何解决Matlab中“matlab can't reload cnngpu.dll”的问题?
- fortran - How do I add a double tab in fortran?
- javascript - 查找常用词并推入新数组
- r - 使用 difftime 和 dplyr 设置函数的参数
- java - 如何在 Java 9+ 中设置默认垃圾收集器?
- python - matplotlib.dates 是否有 AutoMinorLocator 等价物?