Better optimization between fast and small

Vladimir A. Pavlov pv4 at
Thu Oct 19 10:47:12 PDT 2006

On Thursday 19 October 2006 14:37, Norman Urs Baier wrote:
> Am Donnerstag, 19. Oktober 2006 08:20 schrieb Vince Greg:
> > Without compilation my package 80mo
> > With  -Os -s -fno-strict-aliasing my package 14mo
> > With  -O3 -Os -s -fno-strict-aliasing my package 15,2mo
> > I search to have fast programms and small programms

If you had asked me before posting whether these CFLAGS would give you
different results I would say "No". But now I really don't know what
to say. I'm still sure the results would be the same :)

> You cannot "combine" compiler optimisation flags. It is alway the last 
> optimisation flag that counts. So in theory the final binaries should be 
> equal when using either of
> -Os -s -fno-strict-aliasing
> or:
> -O3 -Os -s -fno-strict-aliasing

It's so according to "man gcc".

> In fact the optimisation flags are only aliases and turn on other more 
> detailed flags.
> So, what -Os in fact does is, it turns off:
>           -falign-functions  -falign-jumps  -falign-loops 
>           -falign-labels  -freorder-blocks  -freorder-blocks-and-partition 
>           -fprefetch-loop-arrays  -ftree-vect-loop-version

Sorry, that's wrong.

The man page says

-Os Optimize for size.  -Os enables all -O2 optimizations that do not
           typically increase code size.  It also performs further
           optimizations designed to reduce code size.

           -Os disables the following optimization flags:
           -falign-functions -falign-jumps  -falign-loops
           -falign-labels -freorder-blocks
           -freorder-blocks-and-partition -fprefetch-loop-arrays

Note, "it also performs further optimizations...".

If you don't trust the man page, use the source. gcc-4.1.1/gcc/toplev.c
contains these lines:

/* Nonzero means do optimizations.  -O.
   Particular numeric values stand for particular amounts of
   optimization; thus, -O2 stores 2 here.  However, the optimizations
   beyond the basic ones are not controlled directly by this variable.
   Instead, they are controlled by individual `flag_...' variables that
   are defaulted based on this variable.  */

int optimize = 0;

/* Nonzero means optimize for size.  -Os.
   The only valid values are zero and nonzero. When optimize_size is
   nonzero, optimize defaults to 2, but certain individual code
   bloating optimizations are disabled.  */

int optimize_size = 0;

And many functions use checks like "if (optimize >= 2) ..." or
"if (!optimize_size) ..." so -Os means something greater than just an
"alias for several other flags".

> All these pretty, but space consuming optimisation flags, which -O3
> turned on just before.
Yes, don't use -O3. According to documentation using it can either
improve the performance of the resulted binaries or _the reverse_.
-O2 is usually a good choice. If you wonder I've successfully built the
whole LFS (including the toolchain) and some packages from BLFS
including Xorg using these *FLAGS:

CFLAGS="-march=athlon-xp -O2 -s -pipe -fomit-frame-pointer \
-mpreferred-stack-boundary=2 -fno-align-labels -fno-align-jumps \
-fno-align-loops -fno-align-functions"



	because it's my processor.
	a "good choice" :)
	doesn't influence the resulting binary but makes compilation
	faster itself.
	strips liraries and binaries so you don't need running
	"strip --strip-<stuff>" after the build. Some docs say using
	the flag isn't safe but I haven't seen the case it would lead
	to a broken program.
	causes the stack to be aligned on 4 bytes. Besides, it removes
	the commands that are to align tha stack, making binaries and
	libraries smaller.
	removes the code alignment making binaries/libraries smaller.

As a well known rule, using just -Os makes the resulting binaries about
10% smaller and about 10% slower than just -O2.

Concerning your FLAGS I suggest you to USE these ones
CFLAGS="-Os -s -fno-strict-aliasing -fomit-frame-pointer"

Though, I don't know why do you use -fno-strict-aliasing :(

Besides, remember these two notes:
1. Not all programs use CFLAGS you define in your environment. In other
   words, even with CFLAGS="-Os" you will have a few programs compiled
   with -O2. Though, in these cases you can look at the build process
   output to see if the program really use _your_ CFLAGS and if not,
   edit Makefile by hand.
2. Most programs support "install-strip" target as well as "install".
   When the book says "run 'make install' to install the program" I
   recommend you to try to install a program using "make install-strip"
   first. If you see something like
   "make: *** No rule to make target `install-strip'" then do it as
   the book says. The idea behind that is that installing with
   install-strip strips the installed binaries/libraries (just like
   the book says in the chapters "Stripping" and "Stripping again").

Nothing but perfection

More information about the lfs-support mailing list