GNU C modules compiled separately = 37% reduction in speed

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

GNU C modules compiled separately = 37% reduction in speed

Postby smcracraft » 27 Sep 2006, 17:53

Hi,

I recently separated out my program into 5 modules
(instead of 1) and plan for more modules.

I noticed the speed of the program on its current
standard benchmark dropped 37% as a result.

When I combine all the code into one module, eliminate
all but a main include at the top, and recompile,
I get 37% faster than the modularized form.

My question is, does anyone know why this happens?

Stuart
smcracraft
 
Posts: 65
Joined: 15 Jan 2006, 05:38

Re: GNU C modules compiled separately = 37% reduction in spe

Postby Dann Corbit » 27 Sep 2006, 18:55

Because GCC's optimizer had a pre-frontal lobotomy.

Other compilers do not suffer this defect.

One way around it (if you are determined to use GCC) is to have two separate projects for your program.

One project is nicely modularized (for debugging, etc.) and the other one does this:

/* file: cheesy_hack.c contains the following: */
#ifdef _MSC_VER
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <more_include_files_go_here.h>
#include <etc.h>

#include "file1.c"
#include "file2.c"
#include "....c"
#include "filen.c"

and compile that when you want a speed build.
Dann Corbit
 

Re: GNU C modules compiled separately = 37% reduction in spe

Postby smcracraft » 27 Sep 2006, 19:10

Dann Corbit wrote:Because GCC's optimizer had a pre-frontal lobotomy.

Other compilers do not suffer this defect.

One way around it (if you are determined to use GCC) is to have two separate projects for your program.

One project is nicely modularized (for debugging, etc.) and the other one does this:

/* file: cheesy_hack.c contains the following: */
#ifdef _MSC_VER
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <more_include_files_go_here.h>
#include <etc.h>

#include "file1.c"
#include "file2.c"
#include "....c"
#include "filen.c"

and compile that when you want a speed build.


Thanks.

Here's another. This is a label in my makefile which makes
an alternate version of the program from all the C files
strung together with the main header file removed.

As to whether this is an optimal implementation, I don't
know.

At least it preserves my ability to use modules for
debugging and monolithic for performance but not
have to leave GNU C.

Microsoft clearly makes great compilers, no question about it.

Code: Select all
massive.exe: *.c *.h
        rm -f massive1 massive2 massive3 massive.c
        cat *.c > massive3
        egrep -v '#include "main.h"' massive3 > massive2
        echo '#include "main.h"' > massive1
        cat massive1 massive2 > massive.c
        gcc -O2 -DNDEBUG massive.c -o massive.exe


I remember seeing something like this in Crafty's
Makefile many years ago.

Stuart
smcracraft
 
Posts: 65
Joined: 15 Jan 2006, 05:38

Re: GNU C modules compiled separately = 37% reduction in spe

Postby Tord Romstad » 27 Sep 2006, 20:23

Dann Corbit wrote:Because GCC's optimizer had a pre-frontal lobotomy.


It is true that a problem with GCC is that it cannot inline function calls to a function defined in a different source code file, but I find it hard to believe that this alone can reduce the speed by as much as 37%. Are there any other problems with GCC which can harm the speed when using multiple source files?

Other compilers do not suffer this defect.

One way around it (if you are determined to use GCC) is to have two separate projects for your program.

One project is nicely modularized (for debugging, etc.) and the other one does this:

Code: Select all
/* file: cheesy_hack.c contains the following: */
#ifdef _MSC_VER
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <more_include_files_go_here.h>
#include <etc.h>

#include "file1.c"
#include "file2.c"
#include "....c"
#include "filen.c"


and compile that when you want a speed build.


Unfortunately, this won't always work. I like to declare "file-global" variables and functions by using the 'static' keyword. I may have a 'static float Foo = 3.5' in file1.c, and a 'static int Foo = 142857' in file2.c. This will cause an error when attempting to compile the project with the technique you describe.

Tord
User avatar
Tord Romstad
 
Posts: 639
Joined: 09 Oct 2004, 12:49
Location: Oslo, Norway

Re: GNU C modules compiled separately = 37% reduction in spe

Postby Dann Corbit » 27 Sep 2006, 22:42

There are other problems as well.

If your header files are not idempotent, you will get rafts of error messages.

If one C file already #includes another C file, then you cannot blindly execute the technique.

It is not just the inlining that improves with GCC. It also is able to rearrange functions so that locality of reference is better (short jumps instead of long jumps most of the time).

It can also make better decisions about what to inline and what not to inline if it can see every function and how it is used.

Maybe it's somewhat better with GCC 4.x -- I have not done any experiments lately.
Dann Corbit
 

Re: GNU C modules compiled separately = 37% reduction in spe

Postby smcracraft » 27 Sep 2006, 23:03

Hi - my report is based on GCC 4.1.0.

It's a good toy compiler but not for serious stuff in my opinion
unless you want the freebie method.

(I had a better opinion of it before 24 hours ago.)

:-)

Stuart
smcracraft
 
Posts: 65
Joined: 15 Jan 2006, 05:38

Re: GNU C modules compiled separately = 37% reduction in spe

Postby bob » 28 Sep 2006, 02:26

couple of points:

(1) carelessly inlining can hurt program performance by crushing the cache. Inlining has to be done carefully.

(2) the way the source files appear can make a big difference. Lots of small procedures scattered all over are worse than lots of small procedures ordered so that if a calls b, then b is close to a in the source...

There are other issues as well.

I have a simple approach to use both..
objects = crafty.o

or

objects = search.o attacks.o etc...

the file crafty.c #includes the source files into one giant source, but with reasonable ordering as above. I uncomment that when using decent compilers. If the compiler (say a bad version of gcc) looks slow, I will use the individual object files which compiles everything separately to avoid indiscriminant inlining issues.
User avatar
bob
 
Posts: 156
Joined: 10 May 2006, 17:59

Re: GNU C modules compiled separately = 37% reduction in spe

Postby Tord Romstad » 28 Sep 2006, 19:18

smcracraft wrote:Hi - my report is based on GCC 4.1.0.

It's a good toy compiler but not for serious stuff in my opinion
unless you want the freebie method.


GCC is getting a too bad rap in this thread. In my opinion, it's an amazing piece of software. Remember that it supports lots of different platforms, and compiles several different languages (at least C++, Objective-C, Java, Ada and Fortran). Despite this, it manages to be almost competitive with commercial C++ compilers which generate code only for x86 processors. I think this is a fantastic achievement for a free software project.

Tord
User avatar
Tord Romstad
 
Posts: 639
Joined: 09 Oct 2004, 12:49
Location: Oslo, Norway

Re: GNU C modules compiled separately = 37% reduction in spe

Postby mridul » 28 Sep 2006, 21:08

Tord Romstad wrote:
smcracraft wrote:Hi - my report is based on GCC 4.1.0.

It's a good toy compiler but not for serious stuff in my opinion
unless you want the freebie method.


GCC is getting a too bad rap in this thread. In my opinion, it's an amazing piece of software. Remember that it supports lots of different platforms, and compiles several different languages (at least C++, Objective-C, Java, Ada and Fortran). Despite this, it manages to be almost competitive with commercial C++ compilers which generate code only for x86 processors. I think this is a fantastic achievement for a free software project.

Tord


The point is not if it is a monumental piece of software - it might be.
The point is , it is slow and does not do a great job on most platforms it supports - supporting multiple platforms at the cost of not doing a good job of its basic requirements of optimisation is not something to be proud about :wink:
It should be competitive in its basic functionality ... the number of platforms supported , and other things like this are 'gravy' : useful no doubt but not critical.

There are a large number of pretty dodgey set of optimisations in gcc - which might speed up an unoptimum piece of code , not something which has been written with performance also as a criterion like chess engines are.


Mridul
mridul
 
Posts: 48
Joined: 09 Dec 2004, 11:34
Location: Bangalore , India


Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 8 guests