什么是 Ox 优化?
身边经常打 ACMer 可能会经常说到 “开 O1优化”,“开 O2” 这类的名词。结合网上的资料和自己的研究,得出如下结论。
Ox 优化
Ox 代表的是 GCC (GNU Compiler Collection) 编译器当中的一个参数,表示 gcc 编译器当中的优化标识参数。常规使用方式如下:
gcc -O a.c
gcc -O2 b.c
Ox 优化的目标是更小的目标文件和更短的运行速度。我们平时默认使用的是 O0 优化,也就是不进行任何优化。除此之外的优化都会对我们编写的代码进行修改(等价的修改,根据编译原理),会对代码中条件语句、循坏语句等进行优化。所谓的 Ox 是已经被整合成一个单一的参数,在背后还有大量的运行参数,针对不同的情况进行优化。关于更多优化选项的解释请转到该博客自行查询。
O1 优化
对于 O1 优化会开启以下参数(知道这些然而并有没有什么用,可跳过)
在不影响编译速度的前提下,尽量采用一些优化算法减小代码大小和可执行代码的运行速度。开启的优化选项如下:
-fauto-inc-dec
-fbranch-count-reg
-fcombine-stack-adjustments
-fcompare-elim
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-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
-freorder-blocks
-fshrink-wrap
-fshrink-wrap-separate
-fsplit-wide-types
-fssa-backprop
-fssa-phiopt
-fstore-merging
-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-sink
-ftree-slsr
-ftree-sra
-ftree-pta
-ftree-ter
-funit-at-a-time
O2 优化
在 O1 优化的基础上会牺牲部分编译速度,采用几乎所有的目标配置支持的优化算法,用以提高目标代码的运行速度。优化选项如下:
-fthread-jumps
-falign-functions -falign-jumps
-falign-loops -falign-labels
-fcaller-saves
-fcrossjumping
-fcse-follow-jumps -fcse-skip-blocks
-fdelete-null-pointer-checks
-fdevirtualize -fdevirtualize-speculatively
-fexpensive-optimizations
-fgcse -fgcse-lm
-fhoist-adjacent-loads
-finline-small-functions
-findirect-inlining
-fipa-cp
-fipa-cp-alignment
-fipa-bit-cp
-fipa-sra
-fipa-icf
-fisolate-erroneous-paths-dereference
-flra-remat
-foptimize-sibling-calls
-foptimize-strlen
-fpartial-inlining
-fpeephole2
-freorder-blocks-algorithm=stc
-freorder-blocks-and-partition -freorder-functions
-frerun-cse-after-loop
-fsched-interblock -fsched-spec
-fschedule-insns -fschedule-insns2
-fstrict-aliasing -fstrict-overflow
-ftree-builtin-call-dce
-ftree-switch-conversion -ftree-tail-merge
-fcode-hoisting
-ftree-pre
-ftree-vrp
-fipa-ra
O3 优化
除了包含 O2 优化的所有优化选项外,会采用很多向量化的算法,提高代码的并行执行效率,利用 CPU 的流水线、Cache 等。会开启如下优化选项:
-finline-functions // 采用一些启发式算法对函数进行内联
-funswitch-loops // 执行循环unswitch变换
-fpredictive-commoning //
-fgcse-after-reload //执行全局的共同子表达式消除
-ftree-loop-vectorize //
-ftree-loop-distribute-patterns
-fsplit-paths
-ftree-slp-vectorize
-fvect-cost-model
-ftree-partial-pre
-fpeel-loops
-fipa-cp-clone options
使用方法
Attention:
- 请务必了解清楚所参加的竞赛是否允许使用 Ox 优化,避免造成犯规等严重错误。
在算法竞赛当中,因为我们不能直接操作选择编译选项,所以可以在代码中添加对应的预编译参数来实现。假设目前我们有如下代码:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
cout << n << "Welcom to the world of Algorithm" << endl;
return 0;
}
开启优化后:
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
cout << n << "Welcom to the world of Algorithm" << endl;
return 0;
}