[英]Compiler optimizations: Where/how can I get a feel for what the payoff is for different optimizations?
在我对各种编译器书籍和网站的独立研究中,我正在学习编译器可以优化编译代码的许多不同方法,但我无法确定每个优化将给予多少好处。
大多数编译器编写者如何决定首先实现哪些优化? 或者哪些优化值得努力或不值得努力? 我意识到这将在代码类型甚至单个程序之间有所不同,但我希望大多数程序之间有足够的相似性来说,例如,一种给定的技术通常会比另一种技术提供更好的性能增益。
我发现在实现教科书编译器优化时,他们中的一些倾向于反转其他优化所做的改进。 这需要大量的工作来试图找到它们之间的正确平衡。
所以你的问题确实没有一个好的答案。 一切都是权衡。 许多优化在一种类型的代码上运行良好,但对其他类型则是悲观的。 这就像设计一个房子 - 如果你把厨房做得更大,那么食品室就会变小。
构建优化器的真正工作是尝试各种组合,对结果进行基准测试,并像主厨一样,选择合适的成分组合。
舌头在脸颊:
更严重的是,它取决于您的编译器的体系结构和目标。 这是一个人的经历......
寻求“巨额回报”:
去寻找剩余的“低悬的水果”:
保持标记。
看看输出; 修复任何看起来很愚蠢的东西。
通常情况下,组合优化甚至重复优化过程比您预期的更有效。 好处不仅仅是各部分的总和。
您可能会发现引入一个优化可能需要另一个优化。 例如,具有Briggs-Chaitin寄存器分配的SSA确实受益于复制传播。
我不是编译器编写者,但为什么不只是逐步优化代码的部分,一直在进行分析?
我的优化方案通常是:
1)确保程序正常运行
2)找到要优化的东西
3)优化它
4)将测试结果与1中的测试结果进行比较; 如果它们不同,那么优化实际上是一个突破性的变化。
5)比较时序差异
渐渐地,我会更快。
我使用分析器选择要关注的部分。 我不确定通过询问编译器编写者你会得到多少额外信息。
这是学术论文(ACM可能?)可能是最新信息的更好来源之一的主题之一。 如果你真的想知道,最好的办法可能是以未经优化的形式创建一些代码,一些是优化所采用的形式(循环展开等),并实际找出增益可能使用编译器的位置优化已关闭。
值得注意的是,在许多情况下,编译器编写者不会花太多时间(如果有的话)确保他们的库得到优化。 基准测试往往不再强调甚至忽略库差异,大概是因为你可以使用不同的库。 例如,GCC中的置换算法渐近*效率低于尝试置换复杂数据时的效率。 这与在调用交换函数期间错误地制作深拷贝有关。 这可能会在大多数编译器中通过引入rvalue引用(C ++ 0x标准的一部分)得到纠正。 将STL重写得更快非常容易。
*这假设被置换的类的大小是可变的。 例如,如果int的向量更大,则置换int的向量向量将减慢。
可以提供大加速但很少完成的是插入内存预取指令。 诀窍在于提前了解程序想要的内存,从不要求错误的内存,也不要丢失D-cache。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.