Sunday, April 27, 2008

Get your compile optimizations straight

I guess that 90% of all Desktop Linux users probably will never ever have to worry about this, since they'll never compile a single executable in their life. But for people that occasionally compile a program, this post might be interesting, especially since I never ever see people writing about this subject when they talk about compiling programs from scratch. You see, when you compile C/C++ programs on Linux, the compiler (GCC in almost all cases) allows you to set special options to optimize the program for use on a certain CPU model. However, if these options aren't set then any source package you compile will be compiled with whatever default optimization settings the author has set for you. Often this will mean your program will be optimised for generic i686 (Pentium 2/AMD K6-2) processors, with little extra optimization and in some cases even debug signals enabled. Fortunately it's pretty simple to set your own settings that should be used whenever you compile a program. Almost all make scripts use these three environment variables: CHOST, CFLAGS and CXXFLAGS. First you need to figure out what the best flags for your CPU are. To find out exactly what kind of CPU you have, type cat /proc/cpuinfo on the terminal. After that head over to http://en.gentoo-wiki.com/wiki/Safe_Cflags to find the best CFLAGS for your CPU. Once you know what your CFLAGS are, you need to set them before you go compile your source package. Do this using the export command, like this:
export CHOST="i686-pc-linux-gnu" export CFLAGS="-march=pentium4 -O2 -pipe -fomit-frame-pointer" export CXXFLAGS="-march=pentium4 -O2 -pipe -fomit-frame-pointer"
You have to do this before you run the ./configure script for it to have any effect. Also, these variables only last for as lang as your have your terminal open. If you switch to another terminal, or close it, you'll have to export the CFLAGS again. After this, your program should now compile with the CFLAGS you set, you can check this by keeping a close eye on the output when you run make. So now you want to always have these CFLAGS set automatically whenever you start your computer and open a new terminal? Easy! Just edit /etc/environment and add your CFLAGS to that file (without the export part). After that you'll have to restart for the default environment settings to be applied. One CFLAGS option that you might want to change depending on the program you are compiling is the -O# flag. It defines the optimization level used. -O2 stands for normal optimization, whereas -O1 stands for little optimization and -O3 for maximum optimization. The tradeoff for using -O3 instead of -O2 is mostly the memory usage of the program. So normally you'll only want to use -O3 for media programs that you don't run continually on your computer, like mplayer/ffmpeg etc. However when compiling an application that you run all the time, like Firefox, Pidgin or driver modules, I recommend you use -O2 because the small increase in CPU performance doesn't justify the increased memory usage. Besides, -O3 tends to make programs less stable as well.

No comments: