【发布时间】:2011-02-25 07:50:34
【问题描述】:
我正在编写对性能非常关键的科学代码。代码的初始版本已经编写和测试,现在,有了分析器,是时候从热点开始剃须周期了。
众所周知,一些优化,例如循环展开,这些天由编译器比由程序员手动干预更有效地处理。哪些技术仍然值得?显然,我将通过分析器运行我尝试的所有操作,但是如果有关于哪些方法有效哪些方法无效的传统智慧,这将节省我大量的时间。
我知道优化非常依赖于编译器和架构。我正在使用面向 Core 2 Duo 的英特尔 C++ 编译器,但我也对什么对 gcc 或“任何现代编译器”有效。
以下是我正在考虑的一些具体想法:
- 用手动操作的容器/算法替换 STL 容器/算法有什么好处?特别是,我的程序包含一个非常大的优先级队列(当前为
std::priority_queue),其操作需要花费大量总时间。这是否值得研究,或者 STL 实现可能已经是最快的了? - 类似地,对于所需大小未知但上限相当小的
std::vectors,用静态分配的数组替换它们是否有利可图? - 我发现动态内存分配通常是一个严重的瓶颈,消除它可以显着提高速度。因此,我对按值返回大型临时数据结构与按指针返回与按引用传递结果的性能权衡很感兴趣。有没有办法可靠地确定编译器是否会对给定方法使用 RVO(当然,假设调用者不需要修改结果)?
- 编译器的缓存感知能力如何?例如,是否值得研究重新排序嵌套循环?
- 鉴于程序的科学性,浮点数无处不在。我的代码中的一个重要瓶颈曾经是从浮点到整数的转换:编译器会发出代码来保存当前的舍入模式,更改它,执行转换,然后恢复旧的舍入模式 --- 即使程序中没有任何内容改变了舍入模式!禁用此行为显着加快了我的代码速度。是否有任何我应该注意的与浮点相关的类似问题?
- 单独编译和链接 C++ 的一个后果是编译器无法执行看似非常简单的优化,例如将 strlen() 等方法调用移出循环的终止条件。是否有任何像这样的优化我应该注意,因为它们不能由编译器完成,必须手动完成?
- 另一方面,有没有我应该避免的技术,因为它们可能会干扰编译器自动优化代码的能力?
最后,将某些类型的答案扼杀在萌芽状态:
- 我了解优化在复杂性、可靠性和可维护性方面是有代价的。对于这个特定的应用,提高性能是值得的。
- 我知道最好的优化通常是改进高级算法,这已经完成了。
【问题讨论】:
-
你的问题是什么?
-
为@Neil +1。然后,分析您的应用程序,找出瓶颈所在,并优化这些部分。
-
@Carl 当然。这就是我所做的,并且正在做的事情
-
如果您阅读它,问题就在那里。 “哪些技术仍然值得?”
-
@ChrisW:或者您可以将其视为一个需要大量澄清的大问题,或者介于两者之间。 OP 显然对一个主题(如何在现代编译器上对 C++ 程序进行微优化)感兴趣,即使该问题不是规范形式。
标签: c++ optimization x86