This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Performance testing function pointers


I'm trying to determine the performance hit of function pointers so I
can know whether to use them in my tight loops or not.  I figured I'd
share my discoveries.

It appears that function pointers are usually exactly as fast
as direct function calls except that with -O1 they're a few
percentage points slower, and with -O3 (in this specific case)
they're 18-20% faster!

So, I feel that I can use function pointers in my parser without
worrying too much about the speed impact.  Does this agree with common
sense?


THE TESTS:           (skip ahead to see the results)

You can download the files from

    http://www.rinspin.com/bronson/code/gcc/

All tests are compiled from one file, body.c.  The important parts
(the incrementing function, the variables, and the loop) are shown here.

    volatile void inc_j(volatile int *volatile p)
    {
        (*p)++;
    }

    volatile int j = 0;
    volatile int *volatile jp = &j;
    volatile void (*fp)(volatile int *volatile j) = inc_j;

    for(i=0; i<100000000; i++) {
        BODY;	// this line gets replaced with the test code
    }


There are three tests:

null:     increment pointer directly in loop--don't call a function.
            BODY = (*jp)++

direct:   call the inc_j function directly.
            BODY = inc_j(jp)

indirect: call inc_j via function pointer.
            BODY = (*fp)(jp)


The null test demonstrates the loop overhead and dereference/increment
overhead.  Null usually runs at 50% of the speed of the other two tests,
indicating that loop/deref/inc overhead is just about the same as a
single function call.


THE DATA:

Running on an Athlon 1800+, Linux 2.6.5, GCC 3.3.3.  All tests were made
using "make On" where n is one of 0, 1, 2, 3, or s.  All data was
collected using "./process -c 10."

The results shown below are from running process three or four times,
then selecting the run whose percentages fall right in the middle.

All values are in seconds, lower is better.


-O0: direct and indirect are effectively the same

      null: min=0.42420 max=0.46485 avg=0.43353    50.21294%
    direct: min=0.85612 max=0.88417 avg=0.86339    100.00000%
  indirect: min=0.85473 max=0.87790 avg=0.86271    99.92159%


-O1: direct always beats indirect by a few percent.

      null: min=0.27519 max=0.29192 avg=0.28063     50.352%
    direct: min=0.54920 max=0.57965 avg=0.55733    100.000%
  indirect: min=0.56807 max=0.59206 avg=0.58362    104.716%


-O2: indirect usually beats direct but by only 0.5% or so.

      null: min=0.26304 max=0.27796 avg=0.26974     48.549%
    direct: min=0.54633 max=0.56521 avg=0.55561    100.000%
  indirect: min=0.54568 max=0.56065 avg=0.55249     99.437%


-03: indirect always beats direct by a whopping 18-20%!

      null: min=0.26597 max=0.27489 avg=0.26969     39.520%
    direct: min=0.67172 max=0.69771 avg=0.68241    100.000%
  indirect: min=0.54627 max=0.55755 avg=0.55124     80.778%


-Os: direct and indirect are effectively the same

      null: min=0.26752 max=0.27900 avg=0.27334     44.568%
    direct: min=0.60842 max=0.61882 avg=0.61331    100.000%
  indirect: min=0.60749 max=0.62729 avg=0.61494    100.266%


CONCLUSION:

Again, running on an Athlon 1800+, Linux 2.6.5, GCC 3.3.3:

With -O0, function pointers are the same speed
With -O1, function pointers are 3-6% slower
With -O2, function pointers are the same speed
With -O3, function pointers are 18-20% FASTER [1].
With -Os, function pointers are the same speed

[1] However, direct 18-20% SLOWER with -O3 optimization than with -O2. 
This indicates to me that there is some sort of problem with -O3, not
that function pointers could possibly be that much faster than calling
directly.  Otherwise, heck, I've got an easy optimization to add to the
compiler.  :)

    - Scott



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]