现代优化编译器如何确定何时应用某些优化,例如循环展开和代码内联?
由于这两者都会影响缓存,天真内联少于X行的函数,或其他任何简单的启发式,都可能会产生性能更差的代码。那么,现代编译器如何处理这个呢?
我很难找到相关的信息(特别是那些相当容易理解的信息......),我能找到的最好的是wikipedia article。任何细节,书籍/文章/论文链接都非常感谢!
编辑:由于答案主要是关于我提到的两个优化(内联和循环展开),我只是想澄清一下我对所有和任何编译器优化感兴趣,而不仅仅是那两个。我也对可以在提前编译期间执行的优化更感兴趣,尽管JIT优化也是有意义的(尽管程度稍低)。谢谢!
答案 0 :(得分:5)
无论如何,通常是那种天真,并希望它是一种改进。
这就是为什么即时编译是如此成功的策略。收集统计数据,然后针对常见情况进行优化。
参考文献:
答案 1 :(得分:1)
您可以查看Spiral项目。
最重要的是,优化是一项艰难的工作。这部分是为什么gcc编译器有这么多选项的原因。如果您对缓存和页面有所了解,可以手动执行某些操作并请求通过编译器完成其他操作,但是没有两台机器是相同的,因此该方法必须是特殊的。
答案 2 :(得分:1)
简而言之:比我们好!
您可以查看一下:http://www.linux-kongress.org/2009/slides/compiler_survey_felix_von_leitner.pdf
迪迪埃
答案 3 :(得分:1)
好问题。您在询问所谓的推测性优化。
动态编译器同时使用静态启发式和配置文件信息。静态编译器使用启发式和(离线)配置文件信息。最后一个通常被称为PGO(配置文件引导优化)。
有很多关于内联政策的文章。最全面的是
An Empirical Study of Method Inlining for a Java Just-In-Time Compiler
它还包含对相关工作的参考以及对一些被考虑的文章的批评(合理的)。
一般而言,最先进的编译器会尝试使用影响分析来估算投机优化的潜在影响。
P.S。循环展开是一种古老的经典东西,它只能帮助一些只执行数字crunchng操作的紧密循环(没有调用等等)。在现代编译器中,方法内联是更重要的优化。