This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Performance testing shared vs. static libs
- From: Scott Bronson <bronson at rinspin dot com>
- To: Jack Lloyd <lloyd at randombit dot net>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 30 Jun 2004 10:20:33 -0700
- Subject: Re: Performance testing shared vs. static libs
- References: <1088588707.3306.327.camel@lea.rinspin.com> <20040630145852.GA29199@acm.jhu.edu>
Sorry, I should have explained that terminology. :)
"indirect" simply means called via function pointer. (*f)()
"direct" means, of course, called directly. f()
Each test simply calls a trivially small routine 100,000,000 times from
the main C file. The routine is called either directly or indirectly,
and either lives in the C file itself, a static library, or a shared
library.
- Scott
FWIW, the test descriptions from the makefile:
# null: does nothing -- shows overhead of loop and timing code
# direct: times the direct function call
# indirect: times the indirect function call (through function ptr)
# dirstatic: time direct function call to a routine in a static library
# dirpicstatic: same as dirstatic but with position-independent code
# dirshare: time the direct function call to a routine in a shared
library
# indirstatic: time indirect function call to a routine in a static
library
# indirpicstatic: same as indirstatic but with position-independent code
# indirshare: time the indirect function call to a routine in a shared
library
On Wed, 2004-06-30 at 07:58, Jack Lloyd wrote:
> By indirect calling, do you mean a call to a function that's in the shared
> library from another function in the same shared library? Something like:
>
> in_prog() -> in_shlib() -> in_shlib_inner()
>
> Or is there some other meaning that I'm not aware of?
>
> -Jack
>
> On Wed, Jun 30, 2004 at 02:58:51AM -0700, Scott Bronson wrote:
> > I wrote these tests to see how much slower it is to call into a shared
> > library than it is to call into a static library. My intuition would
> > say that shared is slower, of course, but by how much?
> >
> > These timings are calling a routine that simply increments an integer
> > (it's only 8 instructions total), so the differences shown here are
> > pretty much worst-case. For example, if my test says that calling a
> > shared library is 10% slower, but your routine is 80 instructions long
> > (10x larger than mine), then for you, calling a shared library routine
> > would only be a 1% performance hit.
> >
> > The tests shown below were run on Linux 2.6, gcc 3.3.3 on an Athlon
> > 1800. You can retrieve the test code from funcptrs-0.2.tar.gz on:
> >
> > http://www.rinspin.com/bronson/code/gcc/
> >
> >
> >
> > COMPILED RESULTS
> >
> > Shared vs. static
> >
> > Calling a shared library routine is 1-20% slower, with the typical
> > performance hit somewhere around 15%:
> >
> > direct to shared library:
> > -O0=5%, -01=20%, -O2=20%, -O3=1%, -Os=10% slower
> > indirect to shared library:
> > -O0=10%, -01=15%, -O2=15%, -O3=15%, -Os=10% slower
> >
> >
> > PIC (position-independent code) vs. position dependent code:
> >
> > -fPIC (position independent code) doesn't affect the speed of the direct
> > function call at all (except for -Os, where it's 5% slower). However,
> > when calling via function pointer, -fPIC causes a 0 to 30% peformance
> > hit (-O0=0%, -O1=10%, -O2=20%, -O3=30%, -Os=15% slower) over
> > position-dependent code.
> >
> >
> > Static linking vs. compiling directly:
> >
> > As you would expect, statically linking to a routine in a library
> > usually provides exactly the same performance as directly compiling the
> > routine into your program. There are some exceptions, however:
> > -O1 is 5% slower and -Os is 5% faster. This seems really weird to me.
> > Why would it be any different at all?
> >
> >
> > CONCLUSION
> >
> > Yes, calling a shared library routine is slower. But not much. For
> > trivial functions, it might be 30% slower worst case, 15% typical,
> > depending on your code and optimization level. For real-world
> > functions, as long as they're not used in the innermost loops, the delay
> > caused by calling into a shared library is negligible.
> >
> > - Scott
> >
> >
> >
> > DATA:
> >
> > For -O0:
> > Directly calling a shared library routine is 5% slower than calling
> > it statically.
> > Indirect function call: (5% slower than direct)
> > Calling into a shared library is 10% slower than calling statically.
> > (i.e. calling a shared library function indirectly is 15% slower
> > than calling a static library function directly)
> >
> > null: min=0.35936 max=0.37501 avg=0.36353 44.917%
> > direct: min=0.80486 max=0.82058 avg=0.80934 100.000%
> > dirshare: min=0.82967 max=0.87794 avg=0.84628 104.563%
> > dirstatic: min=0.80114 max=0.80580 avg=0.80432 99.379%
> > dirpicstatic: min=0.80263 max=0.82554 avg=0.80936 100.002%
> > indirect: min=0.83391 max=0.85256 avg=0.84431 104.320%
> > indirshare: min=0.91188 max=0.95370 avg=0.93296 115.273%
> > indirstatic: min=0.83172 max=0.86983 avg=0.84892 104.889%
> > indirpicstatic: min=0.83234 max=0.87370 avg=0.84546 104.462%
> >
> >
> > For -O1:
> > calling a shared library routine is 20% slower than calling
> > it statically (for both direct and indirect).
> > Directly calling a static library routine is 5% slower than calling
> > a routine that has been directly compiled in (?!). This is
> > reproducible.
> > For some reason, PIC causes a 10% performance hit in the indirect
> > call, but not in the direct call!
> >
> > null: min=0.24641 max=0.25326 avg=0.24962 48.134%
> > direct: min=0.51562 max=0.51982 avg=0.51859 100.000%
> > dirshare: min=0.62994 max=0.63484 avg=0.63222 121.911%
> > dirstatic: min=0.54484 max=0.54833 avg=0.54584 105.254%
> > dirpicstatic: min=0.54667 max=0.55310 avg=0.55051 106.156%
> > indirect: min=0.53638 max=0.55393 avg=0.54647 105.377%
> > indirshare: min=0.63173 max=0.64108 avg=0.63423 122.299%
> > indirstatic: min=0.51710 max=0.52236 avg=0.51930 100.137%
> > indirpicstatic: min=0.57687 max=0.57940 avg=0.57802 111.460%
> > For -O2:
> > calling a shared library routine is 20% slower than calling
> > it statically (for both direct and indirect).
> > Directly calling a static library routine is 5% slower than calling
> > a routine that has been directly compiled in (?!). This is
> > reproducible.
> > For some reason, PIC causes a 20% performance hit in the indirect
> > call, but not in the direct call!
> >
> > null: min=0.25051 max=0.25293 avg=0.25157 48.603%
> > direct: min=0.51552 max=0.52036 avg=0.51761 100.000%
> > dirshare: min=0.63215 max=0.63767 avg=0.63372 122.432%
> > dirstatic: min=0.51592 max=0.51873 avg=0.51756 99.991%
> > dirpicstatic: min=0.51541 max=0.52058 avg=0.51775 100.027%
> > indirect: min=0.51572 max=0.52056 avg=0.51831 100.136%
> > indirshare: min=0.60469 max=0.60900 avg=0.60630 117.135%
> > indirstatic: min=0.51512 max=0.51920 avg=0.51735 99.950%
> > indirpicstatic: min=0.63046 max=0.64098 avg=0.63390 122.466%
> >
> >
> > For -O3:
> > It doesn't matter if youre callind a shared library, static
> > library, or your own code, or -fPIC or not. All direct calls
> > are very close to each other (about 1%).
> >
> > We do see that indirectly calling your own code or a static
> > library goes 10% faster than direct (as found in the previous
> > battery of tests).
> > Indirectly calling a shared library takes 15% longer than
> > indirectly calling a static library (and 5% longer than directly
> > calling either static or shared).
> > PIC continues to cause a 20% performance hit for indirect.
> >
> > null: min=0.24947 max=0.25187 avg=0.25082 43.595%
> > direct: min=0.57265 max=0.57676 avg=0.57534 100.000%
> > dirshare: min=0.58120 max=0.58617 avg=0.58403 101.509%
> > dirstatic: min=0.57705 max=0.59201 avg=0.58076 100.942%
> > dirpicstatic: min=0.57274 max=0.57839 avg=0.57535 100.001%
> > indirect: min=0.51557 max=0.51962 avg=0.51780 89.999%
> > indirshare: min=0.60617 max=0.60948 avg=0.60813 105.699%
> > indirstatic: min=0.51572 max=0.51917 avg=0.51813 90.056%
> > indirpicstatic: min=0.62970 max=0.63533 avg=0.63271 109.970%
> >
> > For -Os:
> >
> > Calling a shared library takes 10% longer than static (both direct and
> > indirect)
> > Calling a static library is 5% faster than calling direct code?!?!
> > -fPIC causes a 5% performance hit direct and a 15% performance hit
> > indirect.
> >
> > null: min=0.25008 max=0.25290 avg=0.25153 43.712%
> > direct: min=0.57253 max=0.57886 avg=0.57543 100.000%
> > dirshare: min=0.62959 max=0.63425 avg=0.63178 109.793%
> > dirstatic: min=0.54431 max=0.54895 avg=0.54653 94.977%
> > dirpicstatic: min=0.57430 max=0.58078 avg=0.57699 100.270%
> > indirect: min=0.57590 max=0.57842 avg=0.57706 100.283%
> > indirshare: min=0.63282 max=0.63675 avg=0.63517 110.382%
> > indirstatic: min=0.57224 max=0.57681 avg=0.57524 99.966%
> > indirpicstatic: min=0.65924 max=0.66185 avg=0.66071 114.819%
> >