【发布时间】:2019-04-10 01:59:39
【问题描述】:
我知道标题有点混乱。让我用一点背景来澄清我的问题:
就执行时间而言,当我使用-O1 标志与-O0 标志编译它时,我的程序的行为很奇怪。我知道-O1 标志做了很多优化,例如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) $^
用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+ 给出了非常相似的结果。 (通过结果,我的意思是执行时间)
我已经用-Q --help=optimizers 检查了这两个编译,并且输出确认两者都启用了相同的标志。
接下来对我来说是比较汇编代码。在此之前,我想在这里问一下是否有人知道为什么会发生这种情况。我没有包含源代码,因为似乎问题与源代码无关。但是,如果需要,我可以附上它。
g++ 版本:g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
【问题讨论】:
-
定义
strangely,提供MCVE,解释你是如何为你的程序计时的。 -
并非所有由
-Ox标志启用的优化都可以单独启用/禁用。并非所有由-Ox标志启用的优化都记录在案。 -
当一个程序根据优化标志表现出不同的行为时,通常是因为它调用了未定义的行为(这是程序中的一个错误)。您应该发布minimal reproducible example,以便我们(也许)可以帮助您找到您的错误。
标签: c++ c++11 gcc compiler-errors g++