为什么我在分析器中看到 __scalbnf?
Why do I see __scalbnf in my profiler?
我正在使用 perf
分析一些 C++ 代码,我发现 __scalbnf
和 __wrap_scalbnf
占用了 运行 的大部分时间。我查了一下这些函数是什么,我最好的猜测是我通过调用 std::exp
来调用它们。但是我希望能够确认这一点。有什么地方可以让我看到实现 std::exp 的 C++ 代码来确认这一点吗?或者对我(C++ 业余爱好者)来说,开始深入研究并了解正在发生的事情的最佳方式是什么?
谢谢。
要确认 std::exp
是 __scalbnf
和 __wrap_scalbnf
的原因,您可以将 std::exp
调用替换为:
- 一个恒等函数 returns 输入值
- 或通过替代 exp 实现(例如 fm_exp,发现 here)
然后,如果您仍然在探查器输出中看到 __scalbnf
和 __wrap_scalbnf
,则表示它不是来自 std::exp。
在 __scalbn
上设置断点。 运行 你的程序。查看回溯(在 GDB 中,bt
)。调用树将显示 exp()
是 __scalbn
.
的父函数
如果一个函数有多个调用者,第一个命中可能不是来自您正在分析的"hot"函数。
要真正弄清楚哪个上层函数(包括它的子函数)负责使用大量时间,请参阅 linux perf: how to interpret and find hotspots。自上而下的分析可以找到昂贵的函数,这些函数在调用其他函数时完成所有工作,即使这些其他函数也有 "innocent" 个调用者。 (例如 memcpy
被大量使用并且通常是不可避免的,但是您想要找到的是调用者使用它太多并且可以更好地优化。或者根本不调用。)
顺便说一句,是的,glibc 的数学库 exp()
实现确实在内部使用了 __scalbn
。我不确定实现有多糟糕,但我没有看到 x86-64 的 asm 版本,只有这个纯 C 版本。 https://code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c.html. (For __scalbnl(long double)
there's https://code.woboq.org/userspace/glibc/sysdeps/x86_64/fpu/s_scalbnl.S.html,对 80 位浮点数使用 x87 fscale
指令。但是其他尺寸只有 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()
而没有完美的准确性,请参阅 (那是 float
,而不是 double
。我忘记了是否有这样的答案双重版本)。
还相关:.
我正在使用 perf
分析一些 C++ 代码,我发现 __scalbnf
和 __wrap_scalbnf
占用了 运行 的大部分时间。我查了一下这些函数是什么,我最好的猜测是我通过调用 std::exp
来调用它们。但是我希望能够确认这一点。有什么地方可以让我看到实现 std::exp 的 C++ 代码来确认这一点吗?或者对我(C++ 业余爱好者)来说,开始深入研究并了解正在发生的事情的最佳方式是什么?
谢谢。
要确认 std::exp
是 __scalbnf
和 __wrap_scalbnf
的原因,您可以将 std::exp
调用替换为:
- 一个恒等函数 returns 输入值
- 或通过替代 exp 实现(例如 fm_exp,发现 here)
然后,如果您仍然在探查器输出中看到 __scalbnf
和 __wrap_scalbnf
,则表示它不是来自 std::exp。
在 __scalbn
上设置断点。 运行 你的程序。查看回溯(在 GDB 中,bt
)。调用树将显示 exp()
是 __scalbn
.
如果一个函数有多个调用者,第一个命中可能不是来自您正在分析的"hot"函数。
要真正弄清楚哪个上层函数(包括它的子函数)负责使用大量时间,请参阅 linux perf: how to interpret and find hotspots。自上而下的分析可以找到昂贵的函数,这些函数在调用其他函数时完成所有工作,即使这些其他函数也有 "innocent" 个调用者。 (例如 memcpy
被大量使用并且通常是不可避免的,但是您想要找到的是调用者使用它太多并且可以更好地优化。或者根本不调用。)
顺便说一句,是的,glibc 的数学库 exp()
实现确实在内部使用了 __scalbn
。我不确定实现有多糟糕,但我没有看到 x86-64 的 asm 版本,只有这个纯 C 版本。 https://code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c.html. (For __scalbnl(long double)
there's https://code.woboq.org/userspace/glibc/sysdeps/x86_64/fpu/s_scalbnl.S.html,对 80 位浮点数使用 x87 fscale
指令。但是其他尺寸只有 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()
而没有完美的准确性,请参阅 float
,而不是 double
。我忘记了是否有这样的答案双重版本)。
还相关: