From: witr@rwwa.COM (Robert Withrow)
Subject: Re: Shared lib benchmarks, and experiences
Reply-To: witr@rwwa.com
Organization: R.W. Withrow Associates
Distribution: usa
Date: Tue, 15 Dec 1992 14:14:55 GMT

In article <BzAEnE.GKq@ra.nrl.navy.mil>,
 eric@tantalus.nrl.navy.mil (Eric Youngdale) writes:

| In article <1992Dec14.231025.12627@rwwa.COM> witr@rwwa.com writes:

| >The reason why I bring this up is that I suspect that it is difficult to
| >assign ``compatible'' ``assigned'' addresses except in the case where the
| >libraries are ``substantially identical''.  For example, if the latter library
| >has twice as many entrypoints as the former, this is likely to be a difficult,
| >problem and probably has no general solution.

| The first time
| you build a sharable library, you select how much memory you want for the jump
| vectors[...]

So as long as you reserve enough extra space and you cause (using tools) the
jump table to be ordered appropriately, your libraries can be made forward
compatible.  The following restrictions still apply:

  1) You must reserve enough space, which means wasting address space,
     and, depending on how dynamicly the library changes, you may eventually
     ``run out'' of space unless you are very liberal in what you reserve.
     Neither of these problems is very major, assuming some care and
     forethought in the creation of the library.

  2) You still ``pollute'' the address space of all processes, due to the
     assigned addresses.  I personally think this is a serious drawback
     because this problem only grows worse with time, and cannot ever
     be reduced without creating incompatibility.  And it requires central
     authority...

As a note, the jump table method improves load-time performance at the
expense of per-call run-time overhead.  Most dynamic loaded library
implementations improve run-time performance at the expense of load-time
overhead by using other methods.  I somewhat prefer the latter because most
processes I use (interactively) are long lived.

| Inter-calling (calls within the library) are all resolved by the
| linker without having to even look at the jump table. 

Which, BTW, is a restriction.  A staticly loaded replacement for such
a routine will not be called by the library code.  Typical examples
are malloc() routines...

| There was another objection that has been raised in the past by various
| people, and that is that in the 3/486 architecture there are relatively few
| machine registers compared to something like a VAX.  The PI code that I have
| seen GCC generate always seems to use up one register as a reference pointer of
| some kind or another, and when you reserve this register (usually ebx) for this
| purpose, it is not available to the compiler for other uses, and this could
| lead to poorer performance. 

Given GCC's code generation strategy, this is likely to cause more frequent
reloading.  Smart optimization can reduce this, but there is likely to be
a micro-level performance hit using PIC.  *Macro* level performance is
not affected to the degree that code examination would tend to indicate, due
to program dynamics, and other savings that PIC can enable.  This gets into
nitty details, but suffice to say that in real systems PIC is roughly
performance neutral...

| Anyway, we have been refining the concept for about 6 months, and we
| now have it to a point where the drawbacks are quite minimal.

I agree.  I still think that the benefits of DSLs make them worth the
effort though.  I remember my sigh-of-relief when I went from SVR3 to
SVR4 shared libraries...

-- 
 Robert Withrow, Tel: +1 617 598 4480, Fax: +1 617 598 4430, Net: witr@rwwa.COM
 R.W. Withrow Associates, 21 Railroad Ave, Swampscott MA 01907-1821 USA
Newsgroups: comp.unix.bsd