Can GNOME startup time be improved via ld flags?

Bryan Cantrill, Master DTrace Guru, First Class, spent some time today looking at what exactly GNOME is doing when you login to a Java Desktop System session on Solaris, and posted his findings to his weblog. (The current JDS on Solaris is based on GNOME 2.6, since that's what was the stable release last year when Solaris 10 hit feature freeze. The JDS team is working on an update to GNOME 2.10 now.)

One of the things Bryan found was that a large part of the I/O time was spent loading shared object text. I took a quick look at some of the binaries and libraries using elfdump, and noticed that there were no signs of using flags that could reduce the time needed to load shared libraries at process startup. Some of these (like -z lazyload) defer work until later - others (like -z combreloc) reduce the work needed whenever it happens.

I sent some suggestions to the JDS team on using these flags and others to improve this and suggested especially reading the Performance Considerations chapter of the Solaris Libraries and Linkers Guide for more ideas. I also cc'ed the linker gurus, and Senior Linker Alien Rod Evans added a suggestion to try out the check_rtime perl script on the binaries to check for the recommended flags and whether any of the libraries linked against aren't really needed. It's currently set up for use in the build system of the OS/Networking consolidation (the portion of the Solaris sources already released via OpenSolaris), but should be adaptable to the JDS build system or in fact, any project that wants to try to optimize it's library/linker use on Solaris.

Unfortunately, just tweaking the flags will mostly help Solaris, but the GNU binutils ld used on Linux and some other platforms offers some similar functionality - it recognizes many of the same -z options for instance, though I haven't tried them to see how they compare.

Something that may help more on both platforms is ensuring the libraries listed in the various .pc files for GNOME only list the direct requirements, not all the dependencies they depend on as well. For instance, look at what is linked into every program on Solaris that uses the gtk toolkit:

alanc@unknown:~ [2] pkg-config --libs gtk+-2.0
-lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lmlib -lpangoxft-1.0 
-lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0
But if you run elfdump -d /usr/lib/ you'll see already lists those dependencies, so duplicating them in the applications simply wastes time as the linker at runtime will load and have to check the same list of libraries it already checked in the application (though it should find it's already taken care of them and doesn't duplicate all the work). Additionally it hardcodes in the applications knowledge of the internals and backends used that they shouldn't need to know about, and makes it harder to change or replace one of them. While all those libraries need to be listed when statically linking, or on older systems (mainly pre-ELF I think), the pkg-config entries should be streamlined when using ELF shared libraries on modern systems.

[Technorati Tags: , , , ]
[Now Playing: Deep Space 9 series finale (recorded today off Spike TV by our TiVo)]


Something that may help more on both platforms is ensuring the libraries listed in the various .pc files for GNOME only list the direct requirements, not all the dependencies they depend on as well.

Newish gnu ld (2.16 at least and probably earlier) has a --as-needed flag for exactly this reason:

% gcc -Wall -o xdemo xdemo.c -Wl,--as-needed -L/usr/X11R6/lib -lX11 -lm
% ldd xdemo =>  (0xffffe000) => /usr/X11R6/lib/ (0xb7efd000) => /lib/tls/ (0xb7de3000) => /lib/ (0xb7ddf000)
        /lib/ (0xb7feb000)

ELF specifies symbol lookup to be breadth-first, so while narrowing the tree width at any point helps, narrowing it near the top helps most. I'm not sure if --as-needed works correctly with weak symbols though, if it doesn't then its usefulness drops significantly.

Also, if i remember my discussions with the PaX team correctly, -z defs allows you to emit some section or other as read-only, which can then be shared between multiple instances of the module. There's also a small security benefit to not allowing the tables to be rewritten by an attacker (which is why PaX cares).

Ulrich Drepper's DSO howto should also be on the required reading list.

Posted by ajax on July 12, 2005 at 04:23 AM PDT #

Some versions of pkg-config did just what you suggested. It produced a host of problems so it was turned off again, before returning in the form of "private dependencies". The problem is else that some libraries like gtk+ expose the API (and thereby the ABI) of underlying libraries like glib so you need to make sure to link the application with glib as well as gtk+. Failure to do so can give interesting results if you have a gtk 2 which links to a newer glib (say glib 3, once that comes out) and the ABI has changed. Of course, if applications made sure not to use data structures or functions from underlying libraries, this wouldn't be a problem.

Posted by Tollef Fog Heen on August 07, 2005 at 04:09 AM PDT #

Post a Comment:
Comments are closed for this entry.

Engineer working on Oracle Solaris and with the X.Org open source community.


The views expressed on this blog are my own and do not necessarily reflect the views of Oracle, the X.Org Foundation, or anyone else.

See Also
Follow me on twitter


« July 2016