【问题标题】:Unable to understand compilers' main optimizations无法理解编译器的主要优化
【发布时间】:2009-06-26 15:59:41
【问题描述】:

Martinus gives a good example 的代码,其中编译器在运行时通过计算乘法来优化代码:

Martinus 代码

int x = 0;
for (int i = 0; i < 100 * 1000 * 1000 * 1000; ++i) {
    x += x + x + x + x + x;
}
System.out.println(x);

Constant Folding -compiler 在编译时优化后的代码 (Thanks to Abelenky for pointing that out)

int x = 0;
for (int i = 0; i < 100000000000; ++i) {
    x += x + x + x + x + x;
}
System.out.println(x);

在我看来,这种优化技术似乎微不足道。 我想这可能是 Sun 最近开始忽略的技术之一。

我对编译器进行的两种优化感兴趣:

  1. 在今天的编译器中被忽略的优化,例如在运行时的 Java 编译器中
  2. 当今大多数编译器使用的优化

请把每种优化技术放在一个单独的答案中。

编译器在 90 年代 (1) 和今天 (2) 使用了哪些技术?

【问题讨论】:

标签: optimization compiler-construction


【解决方案1】:

只需购买最新版的龙之书。

【讨论】:

  • @Pod:我有一个。你能推荐一些页面吗?
【解决方案2】:

循环展开怎么样?:

for (i = 0; i < 100; i++)
    g ();

收件人:

for (i = 0; i < 100; i += 2)
{
    g ();
    g ();
}

来自http://www.compileroptimizations.com/。他们还有更多 - 每种技术的答案都太多了。

查看Trace Trees 以获得出色的解释器/即时优化。

【讨论】:

  • @Corbin:感谢您提供的精彩链接!
【解决方案3】:

您的示例中显示的优化,折叠 100*1000*1000*1000 => 100000000000 不是运行时优化。它发生在编译时。 (我什至不会称其为优化)

我不知道运行时发生的任何优化,除非您计算具有 JIT(即时)编译的 VM 引擎。

在编译时发生的优化范围很广,而且通常不容易解释。但它们可以包括内联小函数、为缓存局部性重新安排指令、为更好的流水线或超线程重新安排指令,以及许多其他技术。

编辑:一些 F*ER 编辑了我的帖子……然后投了反对票。我的原始帖子清楚地表明折叠乘法发生在编译时间,而不是运行时间,正如海报所建议的那样。然后我提到我并不认为折叠常量是一种优化。预处理器甚至可以做到。

Masi:如果你想回答这个问题,那就回答这个问题。请勿编辑其他人的答案以使用他们从未写过的文字。

【讨论】:

  • 100*1000*1000*1000 => 100000000000 这在很大程度上是一种优化。这称为常量折叠。
  • 如果你不把那称为优化,那你就错了。
【解决方案4】:

编译器书籍应该提供很好的资源。

如果这很明显,请忽略它,但您询问的是低级优化,这是编译器唯一可以做的。 In non-toy programs, high-level optimizations are far more productive, but only the programmer can do them.

【讨论】:

  • 您的回答表明编译器无法进行高级优化。对吗?
  • 是的(我的意思是他们可以做一些事情)但是要有效地进行高级优化,您需要一些可以识别高成本调用指令的东西,并且可以让您看到原因正在做什么,所以你可以看看是否有更直接的方法来做到这一点。只有程序员才能看到原因。上面的链接展示了一个很好的例子。
  • 我接受这个答案,因为我不明确了解高级优化。
猜你喜欢
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
  • 2011-11-07
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 2019-04-11
相关资源
最近更新 更多