Better optimization between fast and small
Vladimir A. Pavlov
pv4 at bk.ru
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
> -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
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 \
because it's my processor.
a "good choice" :)
doesn't influence the resulting binary but makes compilation
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
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