管道优化,有什么意义吗?

时间:2013-02-02 00:23:09

标签: c++ optimization assembly cpu

另一家公司的一些非常昂贵的程序员告诉我一些针对特定CPU的低级代码优化技巧,包括管道优化,这意味着,在特殊订单中安排代码(内联汇编),使其适合管道更适合目标硬件。

由于存在无序和推测性的执行,我只是想知道有没有点可以做这种低级别的东西?我们大多数都参与高性能计算,因此我们可以专注于一种非常具体的CPU类型来进行优化,但我只是不知道是否有任何意义来进行这种特定的优化,任何人都有这方面的经验,从哪里开始?有这种优化的代码示例吗?非常感谢!

3 个答案:

答案 0 :(得分:5)

我首先要说的是编译器通常充分优化代码(即足够好),只要您的高级代码和算法得到优化,您就不必担心这一点。一般而言,只有在您有确凿的证据证明存在可以量化和跟踪的实际性能问题时,才会进行手动优化。

现在,说到这一点,它总是有可能改善一些事情 - 有时是一点点,有时甚至很多。

如果您使用的是高性能计算游戏,那么这种优化可能有意义。有各种各样的“技巧”可以做,但最好留给真正的专家,而不是胆小的人。

如果您真的想了解有关此主题的更多信息,请首先阅读Agner Fog's website

答案 1 :(得分:3)

管道优化将提高您的计划绩效:

分支和跳转可能会强制您的处理器重新加载指令管道,这需要一些时间。这一次可以专门用于数据处理指令。

用于管道优化的一些独立于平台的方法:

  1. 减少分支数量。
  2. 使用布尔算术
  3. 设置代码以允许条件执行指令。
  4. 展开循环。
  5. Make循环内容很短(可以放入处理器的缓存中) 没有加载)。
  6. 编辑1:其他优化

    1. 通过消除功能和要求来减少代码。
    2. 检查并优化设计。
    3. 审核实施以实现更高效的实施。
    4. 仅在所有其他优化都具有时才恢复为汇编语言 提供的性能很小;仅优化代码 在80%的时间执行;通过剖析找出。
    5. 编辑2:数据优化

      您还可以通过组织数据来提高性能。在网络上搜索“数据驱动设计”或“优化性能数据”。

      一个想法是,最常用的数据应该紧密相连,最终适合处理器的数据缓存。这将降低处理器重新加载其数据高速缓存的频率。

      另一个优化是:加载数据(进入寄存器),对数据进行操作,然后将所有数据写回内存。这里的想法是在处理数据(或寄存器)之前触发处理器的数据高速缓存加载电路。

      如果可以,请组织数据以适合处理器缓存的一个“行”。顺序位置比随机访问位置需要更少的时间。

答案 2 :(得分:1)

总有一些东西可以“帮助”而不是“阻碍”管道中的执行,但对于大多数通用代码而言,高度专业化,我希望编译代码的性能与最好的一样好。你可以在没有高度专业化的代码的情况下获得每种处理器如果你有一个受控制的系统,你的所有机器都使用相同(或少数类似的)处理器模型,并且你知道99%的时间花费在这个特定的功能上,那么可能会有一个好处优化该特定功能以提高效率。

在您的情况下,它是HPC,手写一些低级代码(例如矩阵乘法)以针对您运行的处理器进行优化可能是有益的。但是,这确实需要对处理器有一些合理的了解,因此您需要研究该处理器模型的优化指南,如果可以,请与之前曾在该处理器上工作过的人交谈。

您要注意的一些事情是“注册注册依赖项” - 您需要c = a + b的结果来计算x = c + d - 所以您尝试将这些与其他一些有用的工作分开,这使得x的计算不会被c = a + b计算所阻碍。

缓存预取并且通常关心如何使用缓存也是一个有用的东西 - 不要将有用的缓存数据踢出来,以后需要100条指令,当你存储的结果是1MB的数组时再使用几秒钟可以值得花费大量的处理器时间。

当编译器决定在它自己的优化中改变它时,控制这些东西很难(呃),所以手写汇编程序几乎是唯一的方法。