Author Topic: Optimization  (Read 9849 times)

tobb

  • Guest
Optimization
« on: July 13, 2007, 05:18:37 pm »
Hi,

is there any disadvantage to enable all optimizations in Code::Blocks for the GCC?:
  • Strip all symbols from binary (for size) [-s]
  • Optimize genereted code (for speed) [-O]
  • Optimize more (for speed) [-O1]
  • Optimize evene more (for speed) [-O2]
  • Optimize fully (for speed) [-O3]
  • Optimize generated code (for size) [-Os]
  • Expensive optimizations [-fexpensive-optimizations]


or do they exclude from each other?


Offline darthdespotism

  • Almost regular
  • **
  • Posts: 163
    • Coder's Nemesis
Re: Optimization
« Reply #1 on: July 13, 2007, 05:46:48 pm »
I think (but I'm not sure) you should only enable one -O optimization.

When enabling optimizations your build-time might increase significantly ("Expensive optimizations" does say quite a lot about this)

when using -s no Debug-Symbols are left in the executeable and therefor Debugging is more difficult.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Optimization
« Reply #2 on: July 13, 2007, 07:30:41 pm »
Although you should just read the gcc documentation, here is a brief sum-up:

-s is nonsense if -g (debug symbols) is given. You can do it, but it does not make sense.
-O is the same as -O1. Contrary to the (wrong) description in the dialog, this does not optimize more.
-Os and any other -O are mutually exclusive. You can optimize either for size, or for speed, not both.
Only one of -Os, -O1, -O2 and -O3 will be used, the last one overriding all preceding. Code::Blocks sends the flags to the compiler in the order in which they appear in the list. Custom compiler flags are sent after the builtins, so you can override any options selected in the list by giving a different option manually.
-O and -O2 are always harmless, -O3 is harmless in almost every case (with very, very few exceptions, under very contrieved conditions). These optimisations trade speed for size and identify/eleminate unnecessary/repetitive code using many different techniques.
-fexpensive-optimizations is both a lot more expensive in terms of compile time and time/space tradeoff, but otherwise harmless.

Note that some compiler options that you will find in the documentation may change behaviour in a way that can be hard to predict, so use with care.
Generally, compiling with the correct processor settings and -O3 gives code that is close to the optimum, exotic options rarely yield a huge improvement (but may cause problems that cost you many days to find out).
« Last Edit: July 13, 2007, 07:34:58 pm by thomas »
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Optimization
« Reply #3 on: July 15, 2007, 01:12:05 pm »
-ffast-math' [...] this option should never be turned on together with any `-O' option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ISO rules/specifications for math functions.
That is not quite right. The documentation says that no -O option should ever turn this switch on (i.e. if you specify -O3, then this will not enable -ffast-math behind your back, unless there is an error in gcc), and indeed you can use -O3 with -ffast-math without any problems. It is just that a program compiled with any -O options is still standard-conformant and guarantees a certain behaviour under clearly defined conditions, while a program compiled with unsafe options makes no such claims.

However, it is noteworthy that -funsafe-math cannot produce, but will always produce incorrect results/behaviours. Whether or not those wrong results/behaviours really matter or not depends on the situation, but they are always wrong.

For example, the compiler may simply assume that any input given to a mathematical function is always good and valid, even though if your actual input possibly produces nonsense output.
Or, the compiler may truncate floating point numbers instead of rounding, or it will tell the CPU to treat non-normalized numbers simply as zero.

For some applications this is utterly bad. For many others, it does not matter at all, even though it is technically wrong.

Similar issues arise with floating point numbers every day (even without optimisations), as a certain kind of "uncertainity" is always inherent to floating point numbers. For example, a floating point value in a register is usually not the same as a floating point value in memory that has gone through the same calculations,
and the value in a register will generally not be the same after storing the register to memory and reading it back. Even though common sense tells you that writing a register to memory and reading it back must yield the identical value, that's not the case.
This is because floating point numbers in memory are 32 or 64 bits wide, but FPU registers are internally 80, 96, or 112 bits (or can be 32 bits, if you use SSE math).

Thus, with -funsafe-math, you only make a thing that's blurry already a bit more blurry :)
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."