【问题标题】:What is the optimization level of `-S` switch to GCC`-S` 切换到 GCC 的优化级别是多少
【发布时间】:2014-08-05 01:03:38
【问题描述】:

在这个question中,我遇到了gcc myfile.c -S产生的汇编代码比gcc myfile.c -O0好但比gcc myfile.c -O1差的情况。

在 -O0 时,会生成两个循环。在 -O1 处,两个循环都被优化了。 (感谢@Raymond Chen 的提醒。引用自他的 cmets)(使用 -S 只是优化 一个循环

我在网上搜索,只找到这个:

-S(引自Overall options

在适当的编译阶段之后停止;不要组装。对于每个指定的非汇编输入文件,输出采用汇编代码文件的形式。

默认情况下,源文件的汇编文件名是通过将后缀“.c”、“.i”等替换为“.s”。

不需要编译的输入文件将被忽略。

所以我的问题是:

  • -S 选项在编译文件时的优化级别到底是多少? (-O0.5?)

  • 为什么不直接使用-O0-O1...(或者这是一个错误?)

编辑:您可以使用此site 来帮助您重现问题。代码在我提到的question 中。 (如果你只使用 -S 编译器选项(或不使用编译器选项),你可以获得一个循环省略。)

第 1 步:

打开此site 并在 Code Eidtor 中复制以下代码。

 #include <stdio.h>
 int main (int argc, char *argv[]) {

   unsigned int j = 10;

   for (; j > -1; --j) {    
      printf("%u", j);
   }
 }

第 2 步:

选择g++ 4.8 作为编译器。 编译器选项为空。(或-S)

第三步:

你得到第一种情况。现在,将j &gt; -1 更改为j &gt;= -1 即可看到第二个。

【问题讨论】:

  • -S 不控制优化,它由 -O 开关控制,所以你看到的不应该发生。我也无法重现这一点。请发布一些代码和您用来重现此行为的确切命令。
  • @nos 在这个站点(gcc.godbolt.org),你可以在那个问题中尝试我的代码。如果我把那些代码贴在这里,不会重复吗?
  • @Tony: 这是 GCC 的哪个确切版本?
  • 在上面的网站上你选择了哪个 GCC 版本(网站默认为 clang!)?
  • @Tony 当您发布确切的代码和重现问题的确切步骤时,通常会容易得多,而不是将我们发送到其他问题和网站。我无法重现你的结果,我不知道你做了什么来产生这些结果。

标签: gcc optimization assembly


【解决方案1】:

通过您上次的编辑,现在您实际上在做什么已经有点清楚了,所以:

对于第一种情况,j &gt; -1

这永远不会发生。 j 是一个无符号整数,-1 转换为无符号值将对应一个所有位都已设置的值。这与UINT_MAX 相同,j 永远不会大于此。所以 gcc 消除了循环,因为它的条件总是错误的

对于 2. 的情况,j &gt;= -1:

这可能发生。 j 肯定可以变成(unsigned int)-1,或者上面提到的 UINT_MAX。循环没有消除。

编译文件时-S选项的优化级别到底是多少? (-O0.5?)

优化级别由 -O 标志控制。 -S 不影响优化。如果没有给出-O 标志,则默认优化是-O0(无优化)

【讨论】:

    【解决方案2】:

    -S 没有优化。另一方面,-O0 禁用所有优化,甚至是默认优化

    因此,您看到的效果是,如果您仅使用 -S,您将“启用”默认优化。

    使用-S 和各种-O 选项来查看对汇编代码的影响。

    编辑我从大约 2.6(1994 年)开始使用 GCC。我很确定我记得在某些版本中,编译器会执行默认优化,您可以使用 -O0 禁用这些优化以调试编译器(即gcc ... 崩溃,gcc -O0 ... 不会崩溃 -> 恭喜,您找到了错误)。

    但这里的情况似乎并非如此。对于-S-O0,我得到了相同的汇编器输出,但也没有给出。因此,无论选择哪种优化级别,似乎总是会应用简单的优化(例如 if(0){} 注释掉代码块)。

    因此,我想说的是上面的原始陈述:

    在 -O0 时,会生成两个循环。在 -O1 处,两个循环都被优化了。 (感谢@Raymond Chen 的提醒。引用自他的 cmets)(使用 -S 只优化一个循环)

    一开始就不正确(至少对于 GCC 4.8.2)。唯一的其他选择是 OP (4.8) 使用的 GCC 版本在启用/禁用优化器选项时存在错误。

    【讨论】:

    • 但是在这个站点 (gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html),它说-O0 '减少编译时间,使调试产生预期的结果。这是默认值。 '
    • @Tony:不,不是,尽管文档是这样说的。除非您明确告诉编译器不要使用 -O0 执行此操作,否则始终会执行最少的优化。
    • 达蒙:你确定吗?在这种情况下,应该为 GCC 文档创建错误报告。
    • 刚刚尝试使用 -O0 和没有任何 -O 构建 ~30000 LOC 程序,并且反汇编的可执行文件显示没有差异。
    • 我们在这里讨论的是哪个版本的 GCC?
    猜你喜欢
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 2012-02-28
    • 2011-06-14
    • 2020-07-06
    • 2015-07-05
    相关资源
    最近更新 更多