计算效率高的C ++ - 一般阅读

时间:2012-02-27 11:23:16

标签: c++ performance optimization

我的工作主要是高性能的“科学”计算。我已经做了大约15年了,但直到最近才意识到我的软件浪费了计算时间。简而言之:我编写高效C ++代码的方法不再适用。

我不时会看到一段代码,由一些孩子编写,与我的计算基本相同(相同的算法,类似的方法),但是 - 神奇地! - 表现得更快。在大多数情况下,我甚至无法追踪差异的起源!

我的问题是:我如何学习现代C ++代码优化的艺术?也许SSE上的内容,缓存/内存对齐问题?欢迎任何关于书籍,PDF,文章,练习或网站的建议!

PS。我很清楚这些技巧:

  • 太一般(例如'使用分析器','使用好的算法','去多线程')
  • 琐碎(例如'避免虚函数','Do ++ i代替i ++','启用-O3')
  • 可疑(例如'使用reinterpret_cast重新使用内存<>','Tabularize正弦和余弦','写入内联汇编')
  • 荒谬(例如'做模板元编程')

这些我在问什么。

6 个答案:

答案 0 :(得分:10)

我在科学计算方面工作的时间比OP长,主要是在Fortran中。根据我的经验,这里有一些建议;

1)了解编译器可以做什么。一方面,不要试图在编译器知道的优化技巧上击败编译器,另一方面,要知道编译器仍然不擅长。例如,现在我认为我可以比循环平铺的编译器做得更好。还要了解如何使编译器轻松优化代码。

OP会试图将这一点作为一个过于笼统的建议示例而无法使用。我看到英特尔C ++编译器手册有大约800页的编译器选项文档,还有400页有关优化应用程序的文档。 OP是否已阅读所有这些内容(或首选编译器的类似数量的文档)?

2)随时了解计算机体系结构,特别是内存层次结构和fpus的设计。如果不出意外,这有助于理解人们可以合理预期的性能极限。但它也为程序设计和实施决策提供了输入,并指出了当程序转移到下一代硬件时这些决策应该如何改变。

3)使用库。编写代码作为最后的手段。

4)不要嘲笑诸如模板元编程之类的想法,这些想法在帮助程序员创建快速代码方面享有很高的声誉。研究提升和闪电战。

5)计划表现是一种经验学科。仅相信数据,而不是参数。甚至不是我提出的论点。

最后,即使在大规模的高性能计算中(我最大的工作在10K CPU上运行了几天,所以我对此有一点了解),有时优化的活动是开发时间,而不是执行时间。

PS你有没有问过孩子的指导?

答案 1 :(得分:6)

处理器比15年前快得多。记忆并没有以相同的速度加速。这与更大的数据集相结合,特别是在大型科学模拟中,意味着您必须更仔细地考虑如何访问数据。这可能是其中一个差异。

我发现这些文章很有趣:

http://overbyte.com.au/2011/10/21/optimisationmasterclass1/

http://overbyte.com.au/2011/11/10/optimisation-lesson-2/

它们是由一个我认识的人编写的,他编写了游戏引擎并且现在优化了PS3游戏。您可能会觉得它们很有用。

答案 2 :(得分:3)

我不能称这个人为“小孩”,但你可能会发现这门课很有用: Advanced STL 来自MSDN Channel9的Stephan T Lavavej讲座(ST ++的VC ++团队成员和维护者)。但是,视频的质量对我来说并不好。也许,你会更幸运。

答案 3 :(得分:3)

“计算机体系结构 - 定量方法”一书hennessey和patterson。不是专门针对C ++,而是整体架构更重要。这对HPC来说至关重要,甚至超过任何“技巧和提示”。

答案 4 :(得分:2)

记录时间之前我读了两本帮助我的书:

  1. Bulka& Co.的高效C ++性能编程技术Meyhew
  2. 更有效的C ++
  3. 此外,定期访问BrDobbs,当然还有stackoverflow !!!

答案 5 :(得分:1)

不要忘记网格处理。可以跨多个CPU或多个线程执行长计算。

这是一种改善计算时间的现代方法。

其他人往往是标准的: - 有效使用缓存 - 有效使用懒惰评估

并在完成所有这些操作时避免锁定/解锁。