By: James Crasta
Prelinking is a process that allows you to speed up the process of dynamic
linking. What it does is, through a process of magic that is incredibly
complex, but basically it speeds up the relocation process, in loading
shared libraries.. by setting preferred load addresses.
What is he talking about, you ask? Well, here's how it goes. Dynamically
linked libraries (often referred to as DSO's or in the windows world DLLs)
are libraries which are loaded at runtime. The advantage of shared libraries
versus static libraries is, that it reduces the size of executables, since
each program doesn't need its libraries built in, but will dynamically locate
and use it at run time. This adds some overhead, because the address space of
the library, instead of being known in advance, has to be mapped at runtime.
Another advantage of shared libraries is that due to the magic of copy-on-write, you can save memory when you have multiple programs sharing the same library (though it's not as simple as that.. it is pretty complicated)
Pre-linking sets preferred address space for the libraries to be loaded at. Note they are _preferred_ spaces, and if that address space is not available, then
it will use relocation to load it dynamically.. hence pre-linking is not 100% foolproof.
To prelink, you need at least:
- glibc 2.3.1 or greater
- libelf or elfutils 0.7, though 0.8 is preferred. Latest version as of this writing is 0.84
- Your shared libraries have to be compiled with -fPIC
- the prelink program from ftp://people.redhat.com/jakub/prelink
First, you need to set up a prelink.conf . This file tells prelink
where to search for shared libraries and where to search for apps to
prelink if you decide to use the -a feature to prelink everything.
# /etc/prelink.conf
-l /bin
-l /sbin
-l /usr/bin
-l /usr/sbin
-l /lib
-l /usr/lib
-h /usr/local/lib
-h /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.1
-h /usr/lib/mozilla
-h /usr/X11R6/lib
once you have set this up, you are ready to go.
to prelink an executable, simply:
# prelink /path/to/executable
(note that the path must be an absolute path to the program)
The process of prelinking is reversible, to remove the prelinking simply:
# prelink --undo /path/to/executable
These other flags might also be useful to you:
-v verbose, will show all the libraries it is linking
-n dry run, when used with v will compute libraries but not
modify any executables
-a Prelinks _all_ executables using a recursive search of the directories in prelink.conf
Well, the results with prelinking is mixed. I haven't seen any tests where
prelinking hurt execution speed, but while some people get spectacular
improvements, some people get only minimal improvements. I've combined
data from my tests on mozilla and konqueror, along with
Jekub Jelinek's
tests on konqueror, to see how much elf prelinking really helps.
Tests |
Without Prelink |
With Prelink |
Notes |
Mozilla test 1 |
real 0m1.199s
user 0m0.160s
sys 0m0.020s
|
real 0m1.133s
user 0m0.110s
sys 0m0.020s
|
This test was done by running mozilla with DISPLAY= set to nothing.
basically, it just tests the prelinking stage, not the loading
and connecting to the X server.
|
Mozilla test 2 |
real 0m7.582s
user 0m2.160s
sys 0m0.180s
|
real 0m7.556s
user 0m2.210s
sys 0m0.100s
|
This test was done from the start to finish of mozilla load, with me
exiting as soon as mozilla loaded up. It is not really an accurate test
since user speed also is a factor here.. but to me (the user) I saw no
perceived difference between using prelink and not using it.
|
Konqueror test |
real 0m0.906s
user 0m0.240s
sys 0m0.020s
|
real 0m0.923s
user 0m0.020s
sys 0m0.030s
|
I tried the same with konqueror, another huge C++ app with lots of shared
libraries, but it seems the time didn't change that much, except for a
decent change in user time.. but not a huge difference. Jakub Jelinek
seemed to get better results
|
Jakub Jelinek's Konq test |
real 0m0.510s
user 0m0.510s
sys 0m0.000s
|
real 0m0.011s
user 0m0.000s
sys 0m0.010s
|
Jelinek seemed to get some really good results in loading konq... I don't
know why I wasn't as lucky.
|
In my tests with prelinking, I have been unable to get any sort of results
with it. However, it may work better for you. I guess, the only thing to
do is try it. The process is reversible at least. It won't work on just
any system though, all the libraries have to be compiled with -fPIC and
you need a recent glibc. A recently compiled gentoo will work with prelink
enabled, you will have to kludge with other distros.
Prelink theoretically can cause large performance boosts. It avoids a lot
of calls to mmap that have to be done in the dynamic linking process. On some
systems and with very large programs that load a lot of shared libraries,
prelinking in tests has shown speed increases in load time. Keep in note,
however, that prelinking only really helps the load time of your applications,
for the most part actual runtime speed is not affected.
also note that, in order for prelink to be useful, you need to have all your
libraries compiled with fPIC, and be running glibc 2.3.1 or higher. I don't
know if this is the case for the major distributions, aside from Gentoo
which does support prelinking if you have a recently compiled gentoo setup.
The final word: if you have all the requirements to prelink, and really want
to get that speed bost, it's worth a try. else, wait and see if it catches on
enough that your distribution will begin prelinking executables for you.
- GlibC 2.3 paper: changes in the new GlibC http://people.redhat.com/drepper/lt2002talk.pdf
- Gentoo Linux Prelink Guide http://www.gentoo.org/doc/en/prelink-howto.xml
page last updated 2004-05-17 19:02:10 EDT
|