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

Sel*_*can 3 c++ gcc compiler-errors g++ c++11

我知道标题有点令人困惑.让我用一点背景来澄清我的问题:

当我使用-O1flag vs -O0flag在执行时间方面编译它时,我的程序表现得很奇怪.我知道-O1flag会进行许多优化,例如fauto-inc-dec -fbranch-count-reg -fcombine-stack-adjustments(根据手册页,超过40个).为了找出导致此行为的优化,我计划一次删除一个标记,然后编译并测试以查看是否有变化.

在进行这个实验之前,我想确保编译-O1的程序和编译的程序-O0以及-O1启用(允许调用-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) $^
Run Code Online (Sandbox Code Playgroud)

编译用 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) $^
Run Code Online (Sandbox Code Playgroud)

然而,事实证明-O1-O0+给出了完全不同的结果.尽管存在所有优化差异,-O0-O0+给出非常相似的结果.(结果,我的意思是执行时间)

我检查了两个编译,-Q --help=optimizers输出确认两者都启用相同的标志.

我的下一步是比较汇编代码.在此之前,我想在此问一下是否有人知道为什么会发生这种情况.我没有包含源代码,因为它似乎与源代码无关.但是,如果需要,我可以附上它.

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

Nat*_*ica 7

应用的优化标志-O1仅在启用优化程序时应用.您需要指定-On,n > 0以便优化标志实际执行任何操作.

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


您可以使用标志的-fno形式关闭优化标志.比如说

-fcompare-elim 
Run Code Online (Sandbox Code Playgroud)

标志已打开-O1,您可以使用它将其关闭

-fno-compare-elim 
Run Code Online (Sandbox Code Playgroud)

正如TC所指出的,另一点需要注意的是,并非所有优化都有一个标志,因此没有任何方法可以关闭这些特定的优化.