在哪里学习有关低级、硬核性能方面的知识?

4
这实际上是一个由两个部分组成的问题:
对于那些希望挤出每一个时钟周期的人,他们会谈论流水线、缓存局部性等低级性能技巧。
1. 我看过这些低级性能技巧在各处提到,但我没有看到一个从头到尾的好介绍。有什么资源推荐吗?(谷歌给了我定义和论文,我真的很感激一些实际案例/教程/真实操作材料)
2. 如何测量这种东西?比如说,像某种剖析器一样?我知道我们总是可以改变代码,看到改进并回顾理论,我只是想知道是否有已经建立的工具来完成这项工作。
(我知道算法优化是数量级的关键所在。我对这里的底层技术感兴趣)

2
对于x86机器,请查看此处的信息(http://www.agner.org/optimize/),以及(出于更多历史原因)Michael Abrash的《黑书》(http://www.gamedev.net/page/resources/_/reference/programming/140/283/graphics-programming-black-book-r1698)。 - user786653
QEMU是一款非常有用的工具,用于指令级性能分析。 - SK-logic
啊!所有答案都很好,我该怎么选择一个?! - kizzx2
5个回答

3
回复的共同之处是:“不要过早优化”。正如您提到的,通过更好的设计可以获得比更好的循环更高的性能,而且您的维护者也会感激它。
话虽如此,为了回答您的问题: 学习汇编语言。大量的汇编语言。当你可以移位时,不要使用2的幂次方来进行MUL。学习用异或复制和清除寄存器的奇怪方法。有关具体参考信息,请访问http://www.mark.masmcode.com/http://www.agner.org/optimize/ 是的,你需要计算代码的时间。在*nix上,可以简单地使用time { commands ; },但你可能想使用一个功能齐全的分析器。GNU gprof是开源的,网址是:http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html 如果这真的是你的事情,那就去吧,玩得开心,记住,大量的位级数学。但你的维护者会讨厌你 ;)

3
"而且你的维护者会讨厌你" -- 嗯,这就是代码注释所用的。 - Robert Harvey

2

编辑/重写:

如果你需要书籍,Michael Abrash在这个领域做得很好,比如《汇编语言禅宗》,一些杂志文章,《大黑色图形编程书》等。他调整的许多问题现在已经不再是问题了,问题已经改变。从中你可以得到引起瓶颈的各种想法和解决问题的方法。最重要的是计时,以及了解你的计时测量如何工作,这样你就不会因错误的测量而自欺欺人。计时不同的解决方案,并尝试疯狂、奇怪的解决方案,你可能会发现一个优化,你之前并不知道,直到你暴露出来为止。

我刚开始阅读《See MIPS Run》(早期/第一版),到目前为止看起来不错(请注意,ARM已经取代MIPS成为处理器市场的领导者,所以MIPS和RISC的热度有点过时了)。关于MIPS有很多新旧教科书可供选择。MIPS被设计用于性能(在某些方面牺牲了软件工程师的利益)。

今天的瓶颈分为处理器本身和周围的I/O以及连接到该I/O的内容。处理器芯片本身(对于高端系统)的内部运行速度比I/O能够处理的速度快得多,因此你只能在等待外部操作时进行调整。当火车行驶了3个小时,从火车到目的地节省半分钟的时间并不一定是一个值得优化的决策。

这一切都关乎学习硬件,你可能可以留在1和0的世界中,而不必涉及实际电子技术。但是如果你不真正了解接口和内部结构,你就不能进行太多的性能调整。你可能会重新排列或更改几个指令,并获得一些提升,但要使某个东西变快数百倍,你需要更多的技巧。学习许多不同的指令集(汇编语言)有助于进入处理器。我建议模拟HDL,例如opencores上的处理器,以了解一些人如何设计他们的产品,并掌握如何从任务中真正挤出时钟。处理器知识很重要,需要学习内存接口,媒体(闪存、硬盘等)、显示和图形、网络以及所有这些东西之间的各种接口类型。最重要的是要理解时钟级别或尽可能接近它的水平。


1
我为你修复了那堵文字墙。 - Robert Harvey
2
“x86对于这个并不是一个有趣的平台”-- 不,它只是地球上最常用的平台。 - Robert Harvey
顺便说一句,感谢你对我的回答进行了改进,我本应该在上面花更多的精力和时间。 - old_timer
@dwelch 如果你能支持你的说法“x86是地球上使用最少的处理器之一”,那就太好了。我不是来挑起争端的,但当我告诉我的朋友这种事情时,我希望自己也能有所准备。 - kizzx2

1

英特尔和AMD提供x86和x86-64的优化手册。

http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html/

http://developer.amd.com/documentation/guides/pages/default.aspx

另一个优秀的资源是agner。

http://www.agner.org/optimize/

以下是一些关键点(没有特定顺序):

  • 对齐;内存、循环/函数标签/地址
  • 缓存;非暂态提示,页面和缓存未命中
  • 分支;分支预测和使用比较和移动操作码避免分支
  • 向量化;使用SSE和AVX指令
  • 操作码;避免运行缓慢的操作码,利用操作码融合
  • 吞吐量/流水线;重新排序或交错操作码以执行单独的任务,避免部分停滞并饱和处理器的ALU和FPU
  • 循环展开;为单个“循环比较,分支”执行多次迭代
  • 同步;使用原子操作码(或LOCK前缀)避免高级同步结构

1
我建议阅读《优化汇编子程序:x86平台的优化指南》(Optimizing subroutines in assembly language An optimization guide for x86 platforms),可以在这里下载:http://www.agner.org/optimize/optimizing_assembly.pdf
不过,这是相当深奥的内容哦 ;)

我已经为您修复了裸链接。 - Robert Harvey

1

是的,测量,并且是的,了解所有这些技术。

有经验的人会告诉你“不要过早优化”,我理解为简单地“不要猜测”。

他们还会说“使用性能分析器找到瓶颈”,但我对此有些问题。我听到很多人使用性能分析器的故事,要么非常喜欢它们,要么对其输出感到困惑。Stack Overflow上充满了这样的故事。

我听不到很多关于取得成功的速度提升的故事。

我使用的方法非常简单,我尽量给出了很多例子,包括这个案例


你好,Mike。当我添加了“性能”和“优化”标签时,我有点期待你的出现:P 我已经成功地使用了你的“统计”分析技术,并且有时会进行推广。无论如何,对于这个问题,我真的很想_学习_幕后情况(即我实际上没有需要优化的应用程序)。 - kizzx2
@kizzx2:如果我很容易预测,那我很抱歉 :) 对我来说,面对调整代码的问题是一种真正的享受,只要我有修改它的权利。让我沮丧的是,当我能够准确地知道需要做什么以及大致可以节省多少时,但代码有一个“所有者”,他根本不想这样做。 - Mike Dunlavey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接