Subject: Re: PAM (dynamic linking, dynamic object modules, vs. static)
To: NetBSD-current Discussion List <current-users@NetBSD.ORG>
From: Greg A. Woods <email@example.com>
Date: 09/26/2002 17:15:20
[ On Thursday, September 26, 2002 at 14:39:25 (-0400), Dan Melomedman wrote: ]
> Subject: Re: PAM (dynamic linking, dynamic object modules, vs. static)
> If you have more than one process using a shared library, that library
> is only loaded once, not duplicated like in the static linking case,
> the way I understand these things work. And only pages which are used
> are loaded.
Yes, sort of, but if you have more than one process running from the
same executable then _all_ of its text pages are shared amongst
instances _and_ you don't have to incur the run-time cost of executing
ld.so doing a whole lot of pointer pushing for _every_ exec. Make the
text pages "sticky" and you don't even have to worry about getting them
ready to use on every exec too, even if an instance of the program isn't
> But hey, page granularity is at 4k, so there's still some
> waste. Also, I think "ld" will load unrefernced object files regardless
> - which doesn't happen with static linking.
Indeed there can be waste in dynamic linked process images, but the
worst waste isn't in the memory footprint, but rather in getting them
started -- a waste that happens every time they're run.
The advantages of sharing a few kilobytes of common code from libc
between different programs is quickly outweighed by the overhead
necessary to get that sharing to happen. Static link it and all that
overhead goes away once and for all. I.e. buy purchasing a few
megabytes more memory and/or faster swap devices, you can very quickly
buy back much more performance and it'll keep coming back to you
forever, but if you dynamic link then you keep paying the price of that
overhead forever. Sometimes this can be up to an order of magnitude
more performance in process startup times! That's nothing to sneeze at!
> This is - the way I see it is what's referred to as "DLL Hell" or
> This isn't a fault of shared libraries, but how they're
> managed. This could be addressed in a way by putting a library in its
> own directory (named with a version, crypto sum or some such to prevent
> overwriting, etc.), and maybe make "ld" handle dependencies better in
> some other ways. Why should we dump everything in one directory?
Oh, it's not quite that simple. There are deeper issues, and none of
them are very pretty. Versioning of dynamic linked libraries without
using a language that allows the linker to detect minute API changes at
run-time is _always_ going to lead to issues, esp. when developers are
afraid to bump the major number on some common libraries. I.e. run-time
dynamic binding is almost always best left to interpreted languages
where the necessary checks can be also be done dynamically.
> It all depends on the final goal.
Unfortunately the minor convenience features afforded by dynamic-linked
shared libraries are completely at odds with our current inability to
have the runtime linker detect API changes and all the burden and trust
is placed entirely on the developers to ensure that API changes do not
happen when internal fixes are made to shared libraries. So far the
NetBSD team has had a stellar record at doing this right, and those
doing it have a very deep understanding of the issues and how they
affect the different platforms NetBSD supports. Unfortunately none of
those issues can be dealt with adequately for third-party libraries by a
volunteer organisation, such as all those used in pkgsrc.
> I think people use dynamic linking by
> default even if their stuff could benefit from static.
Indeed they do, and indeed we could all benefit from a bit more static
linking in places where it's very common for many processes to be
frequently started and re-started, such as with most of the base NetBSD
tools. Static linking the entire base NetBSD system (incl. xsrc) can
lead to very noticable performance benefits. I'm typing on a diskless
SS1+ that's running 100% static binaries right now. It's an awful lot
faster at starting programs than it was before I static linked
everything, and it's certainly no slower at running long-lived processes
over their lifetime. The NFS server it loads from also runs 100% static
binaries. On the workstation I've had to add maybe only 4MB of RAM over
what I used before. The server can run builds a lot faster now than it
did before, but it already had adequate memory so I'm not sure how much
more was necessary.
In terms of convenience those static-linked systems are also running all
static-linked pkgsrc programs too. I can now upgrade sensitive programs
immediately, or the components from which they are built, without having
to worry about possibly upgrading all the other programs which might be
built from the same components. I can do this very efficiently too
since all I have to do is "cd /usr/pkgsrc; cvs update" and occasionally
merge a few changes with my local hacks. All the real work of porting
and testing is done by other people and shared with everyone. I win
because I can upgrade my static-only systems with more ease than anyone
else can upgrade their dynamic-linked systems (though unfortunately I
still wear both those hats).
Greg A. Woods
+1 416 218-0098; <firstname.lastname@example.org>; <email@example.com>
Planix, Inc. <firstname.lastname@example.org>; VE3TCP; Secrets of the Weird <email@example.com>