Subject: Re: Enhancing sysctl support in ld.elf_so
To: None <tls@rek.tjls.com>
From: Quentin Garnier <netbsd@quatriemek.com>
List: tech-userlevel
Date: 06/21/2004 23:18:18
Le Mon, 21 Jun 2004 15:33:53 -0400
Thor Lancelot Simon a ecrit :
> On Mon, Jun 21, 2004 at 07:27:16PM +0000, Charles M. Hannum wrote:
> > 
> > Adding extra memory requirements and startup overhead for EVERY SINGLE
> > EXEC() is not a reasonable tradeoff.  This is definitely a
> > non-starter.
> 
> How much memory (and overhead) are we talking about here?  Can we get a
> measurement of this?
> 
> Clearly, if it were one byte, and one nanosecond, this change would be a
> win; if it's 100 kilobytes, and 100ms, it would be a lose.  But the
> added functionality does seem useful (after all, it lets us change libs
> on the basis of any sysctl node, and most ports expose a lot more MD
> nodes, including nodes that could be used to select optimized libraries,
> than the loader actually knows about now) and eliminating users of the
> old sysctl interface seems like a win, too, since it's deprecated and a
> maintenance hassle.

I've done a few quick and dirty tests.  Host is a NetBSD/i386 Celeron
2.6GHz with 512MB of memory.

% ls -l /libexec/ld.elf_so*
-r-xr-xr-x  1 root  wheel  69070 Jun 21 22:26 /libexec/ld.elf_so
-r-xr-xr-x  1 root  wheel  57641 Jun 21 22:02 /libexec/ld.elf_so.2

The smaller is the unpatched one.

test.c is just 'int main() { exit(0); }'.  I compiled three versions of
it, one just compiling the file (test), another adding -lm (testm).  On
i386, libm387 is conditionally loaded upon value of machdep.fpu_present,
so I compiled a third version adding both -lm and -lm387 to be used when
ld.so.conf is empty (thus unconditionally loading libm387, as it would
actually happen on this host).

time measures the following command:

sh -c 'for i in `jot 100000 1`; do ./test; done'

With standard /etc/ld.so.conf:

    test          -> 62.95s user  73.99s system 104% cpu 2:10.64 total
    test+sysctl   -> 63.53s user  74.01s system 104% cpu 2:11.24 total
    testm         -> 78.15s user  93.27s system 103% cpu 2:45.15 total
    testm+sysctl  -> 84.50s user 102.15s system 103% cpu 2:59.92 total

With empty /etc/ld.so.conf:

    test          -> 60.04s user  69.71s system 105% cpu 2:03.56 total
    test+sysctl   -> 60.87s user  70.70s system 105% cpu 2:05.17 total
    testmm        -> 76.06s user  89.23s system 103% cpu 2:39.25 total
    testmm+sysctl -> 76.20s user  90.05s system 104% cpu 2:39.68 total

The result shows a 8.9% increase in loading time when sysctl is actually
used (I tried a second run and got 7%, so it should be around those two
values).

It also shows that sysctl versions are consistently slower, which is
disappointing since in the 'standard ld.so.conf + test' case, the sysctl
version does less than the non-patched version, since it just reads the
sysctl variable and does not try to parse it.  I guess it the cost of
loading the additional 12k in memory and linking them.

It should be noted that only machdep.fpu_present.  I believe that using a
longer MIB or going through subtrees with a lot of children will also slow
down sysctlgetmibinfo().  However, the current ld.elf_so can't be tested
with such nodes.

Andrew, would you see a path for optimisation?

-- 
Quentin Garnier - cube@cubidou.net - cube@NetBSD.org
"Feels like I'm fiddling while Rome is burning down.
Should I lay my fiddle down and take a rifle from the ground ?"
Leigh Nash/Sixpence None The Richer, Paralyzed, Divine Discontents, 2002.