在 callgrind 输出中解释 _dl_runtime_resolve_xsave'2

Ber*_*ARD 1 c++ gcc ld callgrind

查看我的程序运行的 callgrind 输出,我看到 125% !!! 的周期花费在 _dl_runtime_resolve_xsave'2(显然是动态链接器的一部分)中,而 100% 花费在 main 中。但它也说几乎所有花费在 _dl_runtime_resolve_xsave'2 内部的时间实际上都花在了内部方法上(self=0%),但是 callgrind 没有显示该方法的任何被调用者。此外,看起来 _dl_runtime_resolve_xsave'2 是从我正在分析的程序中的多个位置调用的。

我可以理解可能会在 main 之外花费一些时间,因为我正在分析的程序使用原型模式,并且在加载动态库时正在构建许多对象原型,但这不能接近 25% 的时间特定的运行(因为如果我在没有输入数据的情况下执行该运行,它所花费的时间比我现在正在分析的运行要少几个数量级)。

此外,该程序在程序启动后未使用 dlopen 打开共享对象。一切都应该在开始时加载。

这是 kcachegrind 窗口的屏幕截图: 在此处输入图片说明

我如何解释对 _dl_runtime_resolve_xsave'2 的调用?我需要担心在这种方法上花费的时间吗?

感谢您的帮助。

Flo*_*mer 5

_dl_runtime_resolve_xsave在延迟绑定期间在 glibc 动态加载器中使用。它在第一次调用函数时查找函数符号,然后执行对实现的尾调用。除非您LD_BIND_NOT=1在启动程序时在环境中使用类似的东西,否则这是仅在第一次调用函数期间发生的一次性操作。延迟绑定有一些成本,但除非您有许多函数只被调用一次,否则它不会对执行成本产生太大影响。它更可能报告神器,也许关系到尾调用或颇为奇特XSAVE的使用的指令_dl_runtime_resolve_xsave

您可以通过使用LD_BIND_NOW=1环境变量设置启动程序来禁用延迟绑定,将不会使用动态加载程序trampoline,因为所有功能将在启动时解析。或者,您可以链接-Wl,-z,now以使此更改永久化(至少对于您链接的代码,系统库可能仍对其自己的函数符号使用延迟绑定)。