了解C ++性能的资源?

时间:2012-09-10 17:17:09

标签: c++ performance

我正在寻找能够帮助我深入了解C ++性能的资源(理想情况下是一本书)。这里有更多背景知识:

我编写的服务器软件具有极高的吞吐量要求和/或低延迟要求。我们用C ++编写;现在还没有真正进行辩论。我的大多数同事似乎对C ++性能有了更好的理解。他们有更好的心智模型,因此他们可以判断一定数量的代码何时会在规模上表现不佳。我缺乏这种理解,所以我希望改善我的心理模型。

我特别感兴趣:

  • 了解缓存效果,以及由于对象布局导致的缓存位置如何影响我的代码性能。这是我团队其他成员似乎提出的头号问题。
  • 了解内存分配如何影响性能。我应该使用TCMalloc(或其他mallocs),我应该怎么知道?我应该如何调整各种分配和释放参数?
  • 如何知道对象复制的开销何时重要(例如,应该切换到指针)?
  • 只要我知道何时使用它们,我通常也会对“优化”感兴趣。

我真的不感兴趣的事情:

  • “高性能计算”,这个术语似乎表明更多以数学/模拟为导向的应用程序。
  • 讨论C ++相对于其他语言的性能,因为我坚持使用C ++。

作为一个起点,任何人都知道这本书Efficient C++是否适合该法案?

4 个答案:

答案 0 :(得分:26)

让我将我的建议分成几个部分。

C ++优化

作为一个起点,我强烈推荐Agner Fog的Optimizing software in C++。本手册概述了常见的C ++优化主题。

了解一般的硬件

要拥有良好的C ++性能心理模型,您还需要了解底层硬件。请考虑以下声明:

a[7] = 5;

在C ++语言方面,代码行从性能角度来看很无聊:它只是一次内存写入。但是,在实际硬件上,内存写入的性能可能会有几个数量级的变化。要了解该级别的内容,您需要了解缓存,处理器管道,TLB,分支预测等概念。

作为处理器缓存的快速介绍,我推荐我的文章Gallery of Processor Cache Effects。关于缓存和计算机内存的更深入和更长(> 100页)的讨论是What Every Programmer Should Know About Memory

为了全面了解现代计算机硬件,计算机体系结构:定量方法是通常推荐的书籍。我自己没有读过这本书,而是通过阅读博客和实验来学习。然而,其他人显然发现这本书非常有用。

了解特定处理器

在您提高优化技能的过程中,您会发现识别不同处理器的细节很有用。作为众多例子中的一个例子,不同的英特尔和AMD处理器对使用未对齐的SSE指令(例如_mm_storeu_ps C ++内在函数)有着非常不同的惩罚。

要了解不同处理器的细节,我建议The microarchitecture of Intel, AMD and VIA CPUs: An optimization guide for assembly programmers and compiler makers。事实上,我将继续推荐所有来自Agner Fog的optimization manuals。此外,硬件供应商还提供其特定硬件的文档。

学习使用工具

在优化代码时,拥有良好的C ++和硬件性能心理模型非常有用。但是,学习使用正确的工具至少同样有用。可以说,优化的最佳建议是“先测量!”。仅仅通过考虑它就很难理解即使是简单的代码块的性能。通过运行代码并以各种方式测量它,您将获得大量信息。

这些是一些常见的有用测量:

  • 时间:只需运行代码并测量时间
  • 采样分析器
  • 仪表分析器
  • 处理器计数器

我不会对特定工具提出建议,因为我可能会超出原始问题的范围。而且,工具本身就是一个很大的话题:不同硬件平台,软件平台和成本的工具各不相同(有些是免费的,有些是昂贵的)。

但是,您当然需要注意,要优化C ++代码,您需要了解并使用适当的工具。

答案 1 :(得分:11)

Valgrind应该是你的第一个工具。

Valgrind有很多工具,但是cachegrind是查看算法是否具有良好数据局部性的好方法。这将识别内存瓶颈。 Callgrind是另一个valgrind模块,可以帮助您识别处理瓶颈。

参考文献:

Cachegrind: http://valgrind.org/docs/manual/cg-manual.html

Callgrind: http://valgrind.org/docs/manual/cl-manual.html

答案 2 :(得分:1)

之前的回复给出了最重要的想法。

只有一个警告:做一些分析(valgrind),这就是你将获得快速获胜的地方。在那之后,尝试获取缓存优化,查看SSE ......将需要更多的努力,(至少在开始时)几乎没有什么改进。

此外,C ++是一种庞大的语言,编译器也很神奇。模板,内联等允许编译器进行很好的优化,这在C等其他语言中是不可能的。 因此在考虑使用低级数据结构时要非常小心。这可能会导致性能下降(内存管理中出现更多错误和更多麻烦)。

使用STL和BOOST可能有助于避免一些错误。

答案 3 :(得分:1)

  

要了解该级别的内容,您需要了解缓存,处理器管道,TLB,分支预测等概念。

我想以非常随意的方式进一步讨论这些问题。

  1. 缓存 - 基本上,如果您可以尝试将工作集放在缓存中,那么您的应用程序可以看到巨大的速度增益。
  2. 分支 - 分支需要很长时间,因为它们需要在内存读取时阻塞。例如,即使您最终执行不必要的写操作,x=1也可能比if (needWrite) x=1;更快。
  3. 分支预测 - 由于之前的原因,CPU尝试使用模式匹配算法尝试“猜测”分支的结果。让这个值得猜测可以让你获得速度提升。
  4. 至于处理器流水线,指令级并行,超标量,寄存器重命名等 - 我认为这些大部分都必须由编译器进行优化。