【问题标题】:What exactly happens when -O3 is set设置 -O3 时究竟会发生什么
【发布时间】:2015-12-25 14:31:35
【问题描述】:

我有以下代码:

int main()
{
int i=0;
for(i=0;i<10000000;i++)
        //do something
return 0;
}

当我使用 'gcc -o file file.c' 命令运行此代码时,它会在 244 毫秒内执行,而当我使用 'gcc -O3 file.c -o file' 执行相同的代码时,它会得到在 0 毫秒内执行(非常短的时间,显示为零)。我无法理解 -O3 标志做了什么优化,以使我们在执行中获得很大的速度。

关于“-O3”优化的任何链接、文档或解释(除了 gcc.gnu.org,我已经看到并发现那里的信息不足以为我提供一个体面的解释和对正在发生的事情的洞察力) 非常感谢。

【问题讨论】:

  • 也许它意识到没有使用循环的副作用并替换为 nop
  • 如果您想了解底层发生了什么,请向我们提供由 gcc 生成的汇编代码。现在我们只能猜测。我也认为,//do something 在这种情况下是有意义的。
  • 很大程度上取决于做什么事情做什么!
  • 真正知道发生了什么,您可能应该熟悉编译器和代码生成理论与实践。
  • 查看程序集输出 (gcc -S -O3 file.c)。

标签: c gcc compiler-construction


【解决方案1】:

最终我们需要知道什么 //do something 确实如此。您应该粘贴您使用的确切代码,因为从技术上讲,return 语句将作为循环体执行。

如果你有这样的事情:

int main()
{
    int i=0;
    int junkInteger = 0;
    for(i=0; i < 5 ;i++)
    {
        junkInteger++;  // just to have a body
    }
    return 0;
}

通过优化,您的循环可能会像这样展开,从而导致您的代码变大。

int main()
{
    int i=0;
    int junkInteger = 0;

    // loop gets unrolled
    junkInteger++;
    junkInteger++;
    junkInteger++;
    junkInteger++;
    junkInteger++;
    return 0;
}

当循环展开时,低级汇编/机器代码不必执行加载、存储、比较和分支来管理循环。

你应该用这个再次尝试你的代码:

int main()
{
    int i=0;
    for(i=0;i<10000000;i++)
    {
        //do something
    }
    return 0;
}

在打开和关闭优化的情况下编译它并检查文件大小,甚至放入编译选项以生成汇编代码。通常启用优化后,由于循环展开,代码大小可能会变得更大。尽管代码可以优化,因为主体什么都不做。也许使用 volatile 循环计数器来确保它没有被优化出来。

【讨论】:

    猜你喜欢
    • 2013-06-13
    • 2015-10-23
    • 2011-01-18
    • 2014-08-20
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2019-10-12
    • 1970-01-01
    相关资源
    最近更新 更多