5

I know the title is a bit confusing. Let me clarify my problem with a little background:

My program behaves strangely when I compile it with -O1 flag vs -O0 flag in terms of execution time. I know -O1 flag does many optimizations such as fauto-inc-dec -fbranch-count-reg -fcombine-stack-adjustments (More than 40 according to the man page). To figure out which optimization(s) cause this behavior, I plan to remove flags one at a time then compile and test to see if something changes.

Before doing this experiment, I want to make sure that the program compiled with -O1 and the program compiled with -O0 plus all flags which -O1 enables (Lets call -O0+) behave similarly. Actually, I expect both method should produce the same binary file since the same optimization flags are enabled.

Compilation with O1

CC = g++

CFLAGS = -std=c++11 -Wall -fopenmp
SOURCE = a_count_f.cpp
EXEC = run
INC = inc

all: $(EXEC)
.PHONY: all

$(EXEC): $(SOURCE)
    $(CC) $(CFLAGS) -O1 -o $(EXEC) -I$(INC) $^

Compilation with O0+

CC = g++

CFLAGS = -std=c++11 -Wall -fopenmp
SOURCE = a_count_f.cpp
EXEC = run
INC = inc

OPT_FLAGS = -fauto-inc-dec -fbranch-count-reg -fcombine-stack-adjustments -fcompare-elim -fcprop-registers -fdce -fdefer-pop -ftree-builtin-call-dce -fdse -fforward-propagate -fguess-branch-probability -fif-conversion2 -fif-conversion -finline-functions-called-once -fipa-pure-const -fipa-profile -fipa-reference -fmerge-constants -fmove-loop-invariants -fomit-frame-pointer -freorder-blocks -fshrink-wrap -fshrink-wrap-separate -fsplit-wide-types -fssa-backprop -fssa-phiopt -ftree-bit-ccp -ftree-ccp -ftree-ch -ftree-coalesce-vars -ftree-copy-prop -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-phiprop -ftree-scev-cprop -ftree-sink -ftree-slsr -ftree-sra -ftree-pta -ftree-ter -funit-at-a-time

all: $(EXEC)
.PHONY: all

$(EXEC): $(SOURCE)
    $(CC) $(CFLAGS) -O0 $(OPT_FLAGS) -o $(EXEC) -I$(INC) $^

However, It turned out -O1 and -O0+ give quite different result. Despite of all optimizations differences, -O0 and -O0+ give very similar results. (By results, I mean execution time)

I have checked both compilation with -Q --help=optimizers and the output confirmed that both enables the same flags.

The next for me is to compare assembly codes. Before doing that, I want to ask it here if anyone has an idea why this happens. I didn't include the source code as it seems the problem is not related to source code. But, I can attach it if needed.

g++ version : g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

Seljuk Gulcan
  • 1,826
  • 13
  • 24
  • Define `strangely`, provide MCVE, explain how you timed your program. – SergeyA Nov 06 '18 at 16:25
  • Not all optimizations enabled by `-Ox` flags can be enabled/disabled individually. Not all optimizations enabled by `-Ox` flags are documented. – Jesper Juhl Nov 06 '18 at 16:25
  • When a program behaves differently depending on optimization flags it's very often because it invokes Undefined Behaviour (which is a bug in the program). You should post a [mcve] so we can (maybe) help you find your bug. – Jesper Juhl Nov 06 '18 at 16:35

1 Answers1

11

The optimizations flags applied by -O1 only apply when the optimizer is turned on. You need to specify -On with n > 0 in order for the optimization flags to actually do anything.

To put it another way, -O0 doesn't turn on the optimizer, so the optimization flags don't do anything.


You can turn off optimzations flags by using the -fno form of the flag. For instance the

-fcompare-elim 

flag is turned on by -O1 and you can turn it back off using

-fno-compare-elim 

Another thing to note, as pointed out by T.C., is that not all optimizations have a flag so there isn't any way to turn those particular optimizations off.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Thank you for the response, Then, how can I enable/disable individual optimizations flags? Right now I have 40+ flags which cause the behavior I am interested in. Any subset of these flags might be the real cause. How can I find them? – Seljuk Gulcan Nov 06 '18 at 16:31
  • 1
    Additionally, [many optimizations enabled by -O1/2/3 have no individual flags](https://gcc.gnu.org/wiki/FAQ#Is_-O1_.28-O2.2C-O3.2C_-Os_or_-Og.29_equivalent_to_individual_-foptimization_options.3F). – T.C. Nov 06 '18 at 19:27