简体   繁体   中英

Are there any drawbacks to using -O3 in GCC?

I've been a Software Engineer for 13 years in various languages, though I'm just now making my way into C and later C++. As I'm learning C, I'm using the GCC compiler to compile my programs, and I'm wondering if there are any gotchas to using -O3 or other optimization flags. Is there a chance that my software will break in ways that I won't be able to catch without testing the compiled code, or perhaps during cross-compilation, I might inadvertently mess something up for a different platform.

Before I blindly turn those options on, I'd like to know what I can expect. Also, as -Ofast turns on non-standards-compliant flags, I'm leaning towards not using that. Am I correct in my assumptions that -Ofast will most likely have "side-effects?"

I've glanced over https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html before I posted this question.

The only drawback of -O3 should be the inability to follow the code in a debugger.

The use of -Ofast can affect some of your floating point operations causing rounding errors, but unless you are running specifically long chains of floating point calculations you are unlikely to ever notice.

Broken code (code with bad pointers or statements with undefined behavior) is likely to behave differently at different level of optimization -- the first reaction of many programmers is to blame the compiler -- enabling all warnings and fixing them usually helps.

It's important to remember that almost all compiler optimizations are heuristics . In other words, an "optmization" is only an attempt to make your program more "optimal", but it could very well have the opposite effect. Just because -O3 is supposed to be better than -O2 , and -O2 should be better than -O1 —that doesn't mean that is in fact always how it works.

Sometimes an "optimization" enabled by -O3 might actually slow your program down when compared with the version generated with -O2 or -O1 . You should experiment with different levels of optimization to see what works best for your specific code. You can even turn individual optmizations on and off if you really want to fine-tune it.

So in short—yes, there can be downsides to using -O3 . I have personally observed that a lot of stuff I've written works better with -O2 than with -O3 —but that's really program-specific.


FYI, here's another SO question that's asking why -O2 gives better results than -O3 for a specific program: gcc optimization flag -O3 makes code slower then -O2

Since -O3 starts moving your code around to optimise it, in some cases you may see that your results are different or your breaks.

If you test your code for correctness with -O3 and find an issue that you can't debug, it is recommended to switch to -O0 to see if you get the same behaviour.

"I'd like to know what I can expect"

I've been using C++ (mostly GCC on vxWorks) in embedded systems for more than 2 decades. I have tremendous respect for the compiler writers.


Trust your compiler: IMHO, -O3 has never broken any code ... but has, on occasion, revealed interesting coding errors.


Choose: Teams must choose whether or not to "ship what you test, and test what you ship", regardless of -O1 or -O3 choice. The teams I have worked with have always committed to ship and test with -O3.


Single Step can be un-cooperative: On a personal practice level, when using -O3 code, I typically 'abandon' gdb single step. I make much more use of breakpoints, and there are slight variations in coding choices to make auto variables (stack data) and class data more 'visible'. (You can make the gdb command 'p' your inconvenient friend).


Single Step is Necessary: Please note that even though we "test and ship"d using -O3, we debugged using -O1 code almost exclusively.


Debug is Necesary: The trade off between debugging -01 yet testing and shipping -O3 is the extra re-compiles needed to switch the two executables. The time saved in -O1 to explore, identify, and fix the code bug(s) has to make up the 2 rebuilds (to -01 and back to -O3).


Regression Test Automation: I want to say systems test (aka integration test or regression test) of -O3 has to step it up a notch, but I can't really describe it ... perhaps I should recommend that the level of test automation be higher (every one REGRESSION TESTs!). But I'm not sure. The automation level of regression test probably correlates more to team size rather than performance level.


A 'successful' embedded system does 2 things. It satisfies the requirements. And, I think more importantly, in all human visible behaviour it acts like a lightly loaded desktop. For any action (button press, cable disconnect, test equipment induced error, or even a lowly status light change), the results have no human perceptible delay. -O3 helps. A successful system can be done ... I have seen it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM