带有所有相关优化标志的g ++ O1不等于O0

时间:2018-11-06 16:23:22

标签: c++ c++11 gcc compiler-errors g++

我知道标题有点混乱。让我用一点背景来阐明我的问题:

在执行时间方面,当我使用-O1标志和-O0标志进行编译时,我的程序表现得很奇怪。我知道-O1标志会进行许多优化,例如fauto-inc-dec -fbranch-count-reg -fcombine-stack-adjustments(根据手册页的介绍,有40多个)。为了弄清楚哪个优化导致了此行为,我计划一次删除一个标志,然后进行编译和测试以查看是否有所更改。

在进行此实验之前,我要确保使用-O1编译的程序和使用-O0编译的程序以及-O1启用的所有标志(让我们调用{{1} })的行为类似。实际上,由于启用了相同的优化标志,我希望这两种方法都应产生相同的二进制文件。

使用-O0+

进行编译
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) $^

进行编译
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) $^ -O1给出了完全不同的结果。尽管存在所有优化差异,但-O0+-O0的结果非常相似。 (按结果,我是指执行时间)

我已经用-O0+检查了两个编译,并且输出确认两者都启用了相同的标志。

接下来对我来说是比较汇编代码。在此之前,我想在这里问是否有人知道为什么会这样。我没有包含源代码,因为问题似乎与源代码无关。但是,如果需要,我可以附加它。

g ++版本:-Q --help=optimizers

1 个答案:

答案 0 :(得分:6)

-O1应用的优化标志仅在优化器打开时适用。您需要为-On指定n > 0,以便优化标志实际执行任何操作。

换句话说,-O0不会打开优化器,因此优化标志不会执行任何操作。


您可以使用-fno形式的标志来关闭优化标志。例如

-fcompare-elim 

标志由-O1打开,您可以使用

将其关闭。
-fno-compare-elim 

T.C.指出的另一件事是not all optimizations have a flag,因此没有任何方法可以关闭这些特定的优化。