-O 和 -qoptimize
适用的调用
| 选项 | xlc (编译 C) | xlC (编译 C++) | xlclang(编译 C) | xlclang++(编译 C++) |
|---|---|---|---|---|
| -O, -qoptimize | ✓ | ✓ | ✓ | ✓ |
类别
等效编译指示
| xlc/xlC 和其他遗留的调用命令 | xlclang/xlclang + + 调用命令 |
|---|---|
| #pragma 选项 [否] 优化 | 无 |
用途
指定在编译期间是否优化代码,如果执行优化,请指定优化级别。
语法
缺省值
-qnooptimize , -O0 或 -qoptimize=0
参数
- -O0 | nooptimize | noopt | optimize|opt=0
- 仅执行快速局部优化,例如,对局部公共子表达式进行常量折叠和消除。
除非显式指定了 -qnostrict_induction ,否则此设置意味着 -qstrict_induction 。
- -O | | 优化 | 选择 | -O2 optimize|opt=2
- 执行编译器开发者认为最佳组合的优化,以实现编译速度和运行时性能。 这些优化可能随产品发
行版的不同而改变。 如果需要特定级别的优化,请指定相应的数字值。
除非 -qstrict_induction 或 -qnostrict显式否定此设置,否则此设置意味着 -qstrict 和 -qnostrict_induction。
- -O3 | optimize|opt=3
- 执行内存密集型和/或编译时密集型的其他优化。 当对运行时改进的期望超过对最大限度减少编译资源的关注时,建议使用这些功能。-O3 应用 -O2 优化级别,但具有无限制的时间和内存限制。 -O3 还会执行更高和更激进的优化,这些优化有可能略微改变程序的语义。 编译器在 -O2上保护这些优化。 指定 -O3 时执行的积极优化包括:
- 允许激进代码移动,以及对有可能引发异常的计算进行调度。
负载和浮点计算属于此类别。 此优化具有积极意义,因为它可能会将此类指令放在执行路径上,当它们 可能 未根据程序的实际语义执行时, 将 执行这些指令。
例如,在某些 (但并非所有) 通过循环的路径上找到的循环不变量浮点计算将不会在 -O2 处移动,因为该计算可能导致异常。 在 -O3处,编译器将移动它,因为它无法确定会导致异常。 对于负载的运动也是如此。 虽然从未移动过通过指针的负载,但从静态或堆栈基本寄存器的负载在 -O3处被视为可移动。 通常,由于程序可以包含静态数组的声明,因此在 -O2 上的装入并不是绝对安全的。a(共 10 个元素) 和负载a[60000000003],这可能会导致分段违例。
相同的概念适用于调度。
示例:
在以下示例中,在 -O2处,计算b+c由于以下两个原因,未将其移出循环:
- 它被认为是危险的,因为它是浮点运算
- 它不会在通过循环的每条路径上发生
在 -O3处,将移动代码。
... int i ; float a[100], b, c ; for (i = 0 ; i < 100 ; i++) { if (a[i] < a[i+1]) a[i] = b + c ; } ... - -O2 和 -O3 都符合以下 IEEE 规则。
对于 -O2 ,不会执行某些优化,因为在结果为零的情况下,这些优化可能会产生不正确的符号,并且会除去可能导致某种类型的浮点异常的算术运算。
例如, X + 0.0 不会折叠为 X ,因为在 IEEE 规则下, -0.0 + 0.0 = 0.0为 -X。 在其他一些情况下,某些优化可能会执行优化,从而产生带有错误符号的零结果。 例如, X-Y * Z 可能导致 -0.0 ,其中原始计算将生成 0.0。
在大多数情况下,结果差异对于应用程序并不重要, -O3 允许这些优化。
- 可以重写浮点表达式。
例如,如果存在通过这种重新排列获得公共子表达式的机会,那么可以将诸如 a*b*c 之类的计算重写为 a*c*b 。 用乘数替换除数是重新关联浮点计算的另一个示例。
- 除非明确指定 -qhot 或 -qhot=level=1 选项,否则指定 -O3 意味着 -qhot=level=0。
-qfloat=fltint:rsqrt 缺省情况下使用 -O3设置。
-qmaxmem=-1 默认设置为 ,允许编译器在执行优化时使用尽可能多的内存。 -O3
内置函数不会在 -O3处更改
errno。激进的优化不包括以下浮点子选项:
-qfloat=hsflt | hssngl
-qfloat=hsflt
,或任何其他影响程序精度模式的内容。整数除法指令被认为太危险,即使在 -O3处也无法优化。
请参阅 -qflttrap (-ftrapping-math) ,以查看在使用 -qflttrap 选项指定 optimize 选项时编译器的行为。
您可以使用 -qstrict 和 -qstrict_induction 编译器选项来关闭可能更改程序语义的 -O3 的效果。 将 -qstrict 与 -O3 一起指定将调用在 -O2 上执行的所有优化以及进一步的循环优化。 对 -qstrict 编译器选项的引用可以出现在 -O3 选项之前或之后。
后跟 -O 选项的 -O3 编译器选项使 -qignerrno 处于打开状态。
当 -O3 和 -qhot=level=1 生效时,编译器会将源代码中对标准数学库函数的任何调用替换为对等价 MASS 库函数的调用,如果可能,还会替换向量版本。
- 允许激进代码移动,以及对有可能引发异常的计算进行调度。
- -O4 | optimize|opt=4
- 此选项与 -O3相同,不同之处还在于:
- 将 -qarch 和 -qtune 选项设置为编译机器的体系结构
- 设置最适合编译机器特征的 -qcache 选项
- 设置 -qhot 选项
- 设置 -qipa 选项
注: -O, -qcache, -qhot, -qipa, -qarch和 -qtune 选项的后续设置将覆盖 -O4 选项所隐含的设置。此选项遵循“最后一个选项胜出”冲突解决规则,因此任何由 -O4 修改的选项都可以随后更改。 例如,指定 -O4 -qarch=ppc 将允许积极的过程内优化 ,同时维护代码可移植性。
- -O5 | optimize|opt=5
- 此选项与 -O4相同,不同之处在于:
- 设置 -qipa=level=2 选项以执行完整的过程间数据流和别名分析。
注: -O, -qcache, -qipa, -qarch和 -qtune 选项的稍后设置将覆盖 -O5 选项所隐含的设置。 - -Ofast
- 此选项与 -O3 -qhot -D__FAST_MATH__相同。
使用量
根据附加分析是否检测到进一步的优化机会,提高优化级别可能导致也可能不会导致额外的性能改进。
与其他编译相比,具有优化的编译可能需要更多时间和机器资源。
优化可能会导致语句被移动或删除,通常不应与调试程序的 -g 标志一起指定。 生成的调试信息可能不准确。
当使用 -O 或更高优化时, -qtbtable=small 是默认的。 生成的回溯表没有函数名或参数信息。
如果在命令行上指定了优化级别 -O3 或更高 ,那么 #pragma option_override(identifier,
"opt(level, 0)") 或 #pragma option_override(identifier,
"opt(level, 2)")无法覆盖优化级别设置的 -qhot 和 -qipa 选项。
预定义的宏
- __OPTIMIZE__ 在 -O | O2 生效时预定义为 2; 在 -O3 | O4 | O5 生效时预定义为 3。 否则,将未对其进行定义。
- 当 -O | -O2 | -O3 | -O4 | -O5 和 -qcompact 生效时, __OPTIMIZE_SIZE__ 预定义为 1。 否则,将未对其进行定义。
示例
myprogram.c,请输入:xlc myprogram.c -O3
