g++ O1 is not equal to O0 with all related optimization flags(g++ O1 不等于 O0 与所有相关的优化标志)
问题描述
我知道标题有点混乱.让我用一点背景来澄清我的问题:
I know the title is a bit confusing. Let me clarify my problem with a little background:
就执行时间而言,当我使用 -O1
标志与 -O0
标志进行编译时,我的程序的行为很奇怪.我知道 -O1
标志做了许多优化,例如 fauto-inc-dec -fbranch-count-reg -fcombine-stack-adjustments
(根据手册页超过 40).为了弄清楚是哪些优化导致了这种行为,我计划一次删除一个标志,然后编译和测试看看是否有变化.
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.
在做这个实验之前,我想确保用 -O1
编译的程序和用 -O0
编译的程序加上 -O1 的所有标志
启用(让我们调用 -O0+
)行为类似.实际上,我希望这两种方法都应该生成相同的二进制文件,因为启用了相同的优化标志.
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.
用 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+
给出了非常相似的结果.(通过结果,我的意思是执行时间)
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)
我已经使用 -Q --help=optimizers
检查了两个编译,并且输出确认两者都启用了相同的标志.
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++ 版本:g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
推荐答案
-O1
应用的优化标志只在优化器开启时应用.您需要使用 n > 指定
以便优化标志实际执行任何操作.-On
0
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.
换句话说,-O0
不会开启优化器,所以优化标志不会做任何事情.
To put it another way, -O0
doesn't turn on the optimizer, so the optimization flags don't do anything.
您可以使用标志的 -fno
形式关闭优化标志.比如
You can turn off optimzations flags by using the -fno
form of the flag. For instance the
-fcompare-elim
标志由 -O1
打开,您可以使用
flag is turned on by -O1
and you can turn it back off using
-fno-compare-elim
<小时>
另一件需要注意的事情,正如 TC 所指出的,并非所有优化都有标志 所以没有任何方法可以关闭这些特定的优化.
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.
这篇关于g++ O1 不等于 O0 与所有相关的优化标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:g++ O1 不等于 O0 与所有相关的优化标志
基础教程推荐
- C++,'if' 表达式中的变量声明 2021-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 运算符重载的基本规则和习语是什么? 2022-10-31
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 设计字符串本地化的最佳方法 2022-01-01