_dl_runtime_resolve – 何时将共享对象加载到内存中?

我们有一个高性能需求的消息处理系统。 最近我们已经注意到,第一条消息比后面的消息要长很多倍。 一系列转换和消息增强是在我们的系统中进行的,其中大部分是通过外部库来完成的。

我刚刚分析了这个问题(使用callgrind),比较一个消息的“运行”和许多消息的“运行”(提供比较基准)。

我看到的主要区别是占用了大量时间的函数“do_lookup_x”。 看看这个函数的各种调用,它们似乎都被通用函数调用:_dl_runtime_resolve。 不知道这个函数做了什么,但对我来说,这看起来像第一次使用各种共享库,然后由ld加载到内存中。

这是一个正确的假设吗? 二进制文件不会将共享库加载到内存中,直到它们被准备好使用,因此我们将看到第一条消息的大量减速,但是在后面的任何一条消息中都没有?

我们如何去避免这个?

注意:我们在微秒级别上运行。

Solutions Collecting From Web of "_dl_runtime_resolve – 何时将共享对象加载到内存中?"

ld.so(8)手册页, 环境部分:

  LD_BIND_NOW (libc5; glibc since 2.1.1) If set to a non-empty string, causes the dynamic linker to resolve all symbols at program startup instead of deferring function call resolution to the point when they are first referenced. This is useful when using a debug- ger. 

所以, LD_BIND_NOW=y ./timesensitiveapp

作为Ignacio Vazquez-Abrams的运行时建议的替代方法,您可以在链接时执行相同的操作。 链接共享库时,请将-z now标志传递给链接器。