tags:

views:

37

answers:

2

We have a message processing system with high performance demands. Recently we have noticed that the first message takes many times longer then subsequent messages. A bunch of transformation and message augmentation happens as this goes through our system, much of it done by way of external lib.

I just profiled this issue (using callgrind), comparing a "run" of just one message with a "run" of many messages (providing a baseline of comparison).

The main difference I see is the function "do_lookup_x" taking up a huge amount of time. Looking at the various calls to this function, they all seem to be called by the common function: _dl_runtime_resolve. Not sure what this function does, but to me this looks like the first time the various shared libraries are being used, and are then being loaded in to memory by the ld.

Is this a correct assumption? That the binary will not load the shared libraries in to memory until they are being prepped for use, therefore we will see a massive slowdown on the first message, but on none of the subsequent?

How do we go about avoiding this?

Note: We operate on the microsecond scale.

+3  A: 

From the ld.so(8) man page, ENVIRONMENT section:

   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.

So, LD_BIND_NOW=y ./timesensitiveapp.

Ignacio Vazquez-Abrams
Awesome idea, but saddly not in my version of ld. :-(
windfinder
Which loader are you using then?
Ignacio Vazquez-Abrams
ld -versionGNU ld version 2.17.50.0.6-9.el5 20061020
windfinder
That's the linker, not the loader. Based on the "el5" I'd say that your loader is plenty new enough.
Ignacio Vazquez-Abrams
+1  A: 

As an alternative to Ignacio Vazquez-Abrams's runtime suggestion, you can do the same thing at link time. When you link your shared library, pass the -z now flag to the linker.

caf