编写内联汇编代码比编写常规的c/c++代码要快多少?

How much faster if write in-line assembly rather than regular c/c++ code?

本文关键字:代码 c++ 多少 常规 汇编      更新时间:2023-10-16

我的一位资深同事通过编写内联汇编来优化一个函数(他正在实现图像过滤)。这真的有必要吗?现代的编译器不会为我们做这些吗?一般来说,将C代码转换成汇编代码有多少好处?如果汇编代码确实带来了很多好处,那么我们什么时候应该把C/c++代码转换成汇编代码,什么时候应该让代码保持原样,因为汇编代码很难阅读和维护。

如果你比编译器聪明,你可以在一个特定的平台上通过手工编写汇编来让你的代码更快。

然而,大多数大型C/c++编译器都是非常好的优化器;你不可能比他们聪明。

不,这不是真正必要的,而且使得移植应用程序更加不同。这是内联汇编的主要关注点。

当然,80%的情况下编译器可以做得更好。

  1. 首先找到一个有效的算法。
  2. 然后用清晰可读的代码实现。
  3. 然后评估其性能
  4. 如果你的代码性能不足,考虑替代算法
  5. 重复步骤3和4,直到任一性能可接受或用尽所有算法替代
  6. 喝点咖啡。
  7. 走一走。
  8. 再次重复步骤3和4。
  9. 喝杯啤酒。
  10. 再试几次步骤3和4。
  11. 休息一下
  12. 回到3和4.
  13. 花几年的时间研究CPU的架构,你的代码将在上运行。
  14. 现在考虑手写一些汇编。

我想对于图像过滤,您可能会受益于例如SIMD指令的可用性,但并非所有编译器都可以自动编译您的代码以使用它们,并且不是所有时间。因此,内联汇编或内在特性可以帮助解决这个问题。

我的一个资深同事通过编写内联汇编优化了一个函数(他正在实现图像过滤)。这真的有必要吗?

显然我不能评论你同事的具体情况,但如果有必要,我也不会感到惊讶。有许多专门的指令用于图像过滤器,编译器不一定会使用这些指令。内联汇编通常是访问这些指令(或通过内部函数)的唯一方法。

现在的编译器不会为我们做这些吗?

显然这取决于'that'是什么,但是尽管现代编译器确实擅长生成代码,它们并不是神奇的。通常情况下,你知道一些编译器不知道(或不能)的代码。

如果你的工作涉及高性能代码,那么肯定有一些地方你可以从使用内联汇编(甚至只是编译器的内在)中获得重大改进。

如果汇编代码确实带来了很多好处,我们应该在什么时候把C/c++代码转换成汇编代码,什么时候我们应该保持代码的原形,因为汇编代码很难阅读和维护。

方法如下:

  1. 首先,分析你的代码,看看可以获得哪些潜在的好处。查看反汇编,看看编译器在做什么。如果它已经在做最优的事情,那么就没有进一步的意义了。
  2. 如果有改进的机会,考虑在手写汇编之前使用编译器内部函数,因为它通常更容易维护和更可移植。
  3. 只有当所有这些都失败时,才应该转到内联汇编。

简短的回答是没有必要,更长的回答是……嗯,这要看情况。现代编译器在优化代码方面确实做得很好,但它们不一定能获得人类在优化时所做的所有假设。手工编写的汇编程序可以胜过编译后的代码,但是在可移植性和维护之间需要权衡。

假设您已经确定这段代码是热点,您应该做的第一件事是调整算法,然后调整c++代码以使其更快(例如展开循环),然后调整编译器标志。作为最后的手段,如果您仍然不能使它运行得像您需要的那样快,考虑到您将来在维护和可移植性方面所产生的所有成本,考虑是否值得为手工优化付出代价。

在图像处理方面,我将保持谨慎,因为它取决于输入数据,算法和编译器。Intel的ICC有一个非常好的并行化器和矢量化器来生成SSE代码,在大多数通用的图像处理情况下,它可能很难被手工击败。另一方面,VCC可能不会做得这么好。然而,我希望使用编译器的内在特性而不是内联汇编器可以获得最大的好处。

编程语言的编码非常好。除非您使用非常简单的位操作,如加法、位移位或使用指针或新指令集,否则您应该使用实用的编程语言。在你的生活中,任何事情都不需要汇编语言。标准的c操作调用相关的CPU指令。如果有人做了一个新的CPU,它支持新的指令,而你想使用这些指令,编程语言或库不支持它们,适应需要时间。cpu中的新指令,使事情更快,但你永远不会在像DirectX或Opengl或MMX, SSE之类的团队中工作。想象一下,有一天,像directx或opengl这样的图形库还没有开发出来,而英特尔创建了一些目前没有一种语言支持的指令集,或者在没有开发的库中不存在。然后你会想要从CPU调用一些方法并将你的参数传递给它,以获得更好的性能。您仍然可以在cpu中没有新指令的情况下执行相同的操作。另一个例子,英特尔的一个新cpu可以支持md5哈希检查,这并不意味着你不能使用md5,这意味着一个使用md5指令的库将工作得更快,因为cpu内部有一个独立的实体,它将有效地执行操作。但通常情况下,你会等到有人发布了一个使用md5指令的库到cpu。今天的cpu增加了压缩、哈希校验、加密等指令集。对于某些特定的指令,您将使用汇编语言。而不是简单的加法、乘法、减法或除法,因为你的编程语言已经以最有效的方式使用它们了。