繁体   English   中英

编译器优化:在哪里/如何才能了解不同优化的收益?

[英]Compiler optimizations: Where/how can I get a feel for what the payoff is for different optimizations?

在我对各种编译器书籍和网站的独立研究中,我正在学习编译器可以优化编译代码的许多不同方法,但我无法确定每个优化将给予多少好处。

大多数编译器编写者如何决定首先实现哪些优化? 或者哪些优化值得努力或不值得努力? 我意识到这将在代码类型甚至单个程序之间有所不同,但我希望大多数程序之间有足够的相似性来说,例如,一种给定的技术通常会比另一种技术提供更好的性能增益。

我发现在实现教科书编译器优化时,他们中的一些倾向于反转其他优化所做的改进。 这需要大量的工作来试图找到它们之间的正确平衡。

所以你的问题确实没有一个好的答案。 一切都是权衡。 许多优化在一种类型的代码上运行良好,但对其他类型则是悲观的。 这就像设计一个房子 - 如果你把厨房做得更大,那么食品室就会变小。

构建优化器的真正工作是尝试各种组合,对结果进行基准测试,并像主厨一样,选择合适的成分组合。

舌头在脸颊:

  1. 傲慢
  2. 基准
  3. 困窘

更严重的是,它取决于您的编译器的体系结构和目标。 这是一个人的经历......

寻求“巨额回报”:

  • 本机代码生成
  • 注册分配
  • 指令调度

去寻找剩余的“低悬的水果”:

  • 力量减少
  • 不断传播
  • 复制传播

保持标记。

看看输出; 修复任何看起来很愚蠢的东西。

通常情况下,组合优化甚至重复优化过程比您预期的更有效。 好处不仅仅是各部分的总和。

您可能会发现引入一个优化可能需要另一个优化。 例如,具有Briggs-Chaitin寄存器分配的SSA确实受益于复制传播。

从历史上看,存在“算法”优化,在大多数情况下代码应该从中受益,例如循环展开 (编译器编写者应首先实现那些“记录”和“测试”优化)。

然后有一些优化类型可以从所使用的处理器类型中受益(例如在现代CPU上使用SIMD指令)。

有关参考,请参阅Wikipedia上的编译器优化

最后,可以测试各种类型的优化来分析代码或执行重复执行的准确时间。

我不是编译器编写者,但为什么不只是逐步优化代码的部分,一直在进行分析?

我的优化方案通常是:

1)确保程序正常运行

2)找到要优化的东西

3)优化它

4)将测试结果与1中的测试结果进行比较; 如果它们不同,那么优化实际上是一个突破性的变化。

5)比较时序差异

渐渐地,我会更快。

我使用分析器选择要关注的部分。 我不确定通过询问编译器编写者你会得到多少额外信息。

这实际上取决于你正在编译的内容。 最近在LLVM邮件列表上对此进行了相当好的讨论 ,它当然对于他们可用的优化器有些具体。 他们使用缩写进行了很多优化过程,如果你不熟悉他们正在折腾的任何首字母缩略词,你可以查看他们的传递页面以获取文档。 最终,您可以花费数年时间阅读有关此主题的学术论文。

这是学术论文(ACM可能?)可能是最新信息的更好来源之一的主题之一。 如果你真的想知道,最好的办法可能是以未经优化的形式创建一些代码,一些是优化所采用的形式(循环展开等),并实际找出增益可能使用编译器的位置优化已关闭。

值得注意的是,在许多情况下,编译器编写者不会花太多时间(如果有的话)确保他们的库得到优化。 基准测试往往不再强调甚至忽略库差异,大概是因为你可以使用不同的库。 例如,GCC中的置换算法渐近*效率低于尝试置换复杂数据时的效率。 这与在调用交换函数期间错误地制作深拷贝有关。 这可能会在大多数编译器中通过引入rvalue引用(C ++ 0x标准的一部分)得到纠正。 将STL重写得更快非常容易。

*这假设被置换的类的大小是可变的。 例如,如果int的向量更大,则置换int的向量向量将减慢。

可以提供大加速但很少完成的是插入内存预取指令。 诀窍在于提前了解程序想要的内存,从不要求错误的内存,也不要丢失D-cache。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM