繁体   English   中英

用汇编替换c代码以提高性能的简单示例是什么?

[英]What is a simple example of replacing c code with assembly to improve performance?

我听说游戏开发人员有时会用汇编代码替换部分内循环以提高性能。

这是一个简单的例子?

组装在哪里? 只是内联w / C代码?

谢谢!

编辑:非常感谢代码示例。

我不是一个游戏开发人员,但我几乎只写了汇编代码(我是图书馆作家)。 通常这是出于性能原因,但我也是为了解决编译器错误,或者使用条件标志等硬件功能,这些功能实际上比在C中更容易表达。

我通常在汇编中编写完整的函数,因此我倾向于编写.s文件,这些文件被汇编到目标文件中并链接到可执行文件或库中。 只需要将单个循环移动到汇编中的人经常在其C源中使用内联汇编,大多数编译器都通过某种内在函数支持它。

“简单”的例子非常罕见,因为如果它很简单,编译器就可以做得非常好,并且不需要汇编。

以下是汇编编码专业人员:

  • 汇编代码可以利用处理器的独特指令以及各种专用硬件资源。 另一方面,C代码是通用的,并且必须支持各种硬件平台。 因此,C很难支持特定于平台的代码。

  • 汇编程序员通常非常熟悉应用程序,并且可以进行编译器无法使用的假设。

  • 汇编程序员可以使用人类的创造力; 尽管可能是高级的编译器,但它只是一个自动程序。

另一方面,这里是汇编编码缺点:

  • 汇编程序员必须处理耗时的机器级问题,例如寄存器分配和指令调度。 使用C代码,编译器会处理这些问题。

  • 汇编编码需要DSP架构及其指令集的专业知识,而C编码只需要C语言的知识 - 这是相当常见的。

  • 使用汇编代码,将应用程序从一个平台移植到另一个平台是非常困难和耗时的。 对于C应用程序来说,移植相对容易。

这里开始

这是一个简单的(ish)示例 - Watt-32交换代码

在这种情况下, __asm用于将汇编代码与C / C ++代码整合在一起,以提高性能。 由于这是一种替代的跨平台网络堆栈,因此有许多方面将性能保持在关键位置非常重要。

我几年前放弃了汇编编码,当时我发现优化的C ++编译器会在性能上击败我,因为构建优化器的人会考虑各种各样的事情,比如管道停顿,部分并行执行后续的独立代码片段(一个好的优化器可以重新排列你的代码),汇编代码(难以阅读,难以调试,不可移植)的缺点远远超过它在编译器没有的那些日子里的优势好的优化者。

如果我是你,我不会为正常编程任务的汇编编码而烦恼。 即使您可以在此处或那里保存CPU时钟周期,查看复杂应用程序的整体性能,效果也是可以忽略的。

语法取决于您的编译器; 我使用gcc,它支持几种不同的内联汇编程序代码的方法。

请查看此链接以获取说明和示例: http//www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s4

在PC,Xbox 360或PS3的大多数现代游戏中,你会发现很少的内联汇编。 现代优化编译器在指令调度和寄存器分配方面做得相当不错,因此编写内联汇编的性能增益很少值得付出努力。 Visual Studio中的64位代码甚至不支持内联汇编。

内联汇编对于访问编译器不会自动使用的硬件特定指令非常重要。 使用现代编译器内部函数是访问硬件特定指令的首选方式。 在游戏中,内部函数通常用于数学重码以访问硬件特定的向量数学指令(在PC上使用SSE或在Xbox 360 / PS3 PPU上使用VMX或在PS3 SPU上使用SPU指令集)。 内在函数是特定于平台/编译器的扩展,看起来像常规的C / C ++函数,但直接映射到底层硬件上的单个指令。 您可以在MSDN上的Visual Studio中查看x86和x64内在函数的文档。

在一些游戏中,您仍然可以找到一些在程序集中编写的性能关键代码,但通常整个函数将使用汇编编写,而不是使用C / C ++代码中的内联汇编。 我在过去5年左右的任何代码中都没有在任何PC / Xbox 360 / PS3游戏中看到任何内联汇编。

Michael Abrash写了一本名为“ 图形编程黑皮书”的书 绝对值得一读。 你可以在网上免费的PDF文件在这里

Michael Abrash的经典图形编程黑皮书是迈克尔之前关于汇编语言和图形编程的着作的汇编(包括他在Dobb博士期刊中的“图形编程”专栏)。 本书的重点主要是分析和代码测试,以及性能优化。 它还探讨了Doom和Quake 3-D游戏背后的大部分技术,以及纹理映射,隐藏表面移除等三维图形问题。 感谢Michael提供这本书。

即使你使用像__asm这样的api来内联汇编代码,也会产生一些开销。 编译器将首先转储所有yr寄存器(或者您在内联代码中使用的寄存器,具体取决于编译器选择优化),然后内联代码,然后恢复这些寄存器。 我觉得如果内联汇编代码没有显着的优势,那么应该避免,考虑到可维护性,移植性,正确性,可读性和性能之间的权衡。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM