现代游戏代码中实际使用了多少汇编程序?[关闭]


21

平均而言,现代游戏代码中多久使用一次汇编?

特别是在已经具有良好C ++编译器的平台(例如x86,PPC或ARM)上,因为我认为嵌入式系统上的游戏会大量使用汇编语言。


4
C ++不能编译为汇编程序-可以编译为机器代码。汇编语言是一种直接指定要生成的机器代码的方式。
Kylotan

6
C ++(通常)实际上并未编译为程序集,而是直接编译为机器代码。问题可能是指有多少个手写程序集链接到项目中或被编写为嵌入式程序集。

1
无论如何,我认为这个问题没有实用,有用的答案。它基本上取决于类似的因素,其中许多因素都是主观的(即,代码编写者的意见)。

1
如今

4
@Legion-您可以使编译器/ IDE 发出程序集,但这并不意味着编译器会在正常编译过程中生成程序集。它没有必要这样做,因此大多数都不需要这样做。

Answers:


29

答案取决于您所说的“游戏”和“二手”的含义。我假设“使用”的意思是“在特定游戏项目的过程中编写的”。

根据我的经验和与我交谈过的人的轶事数据:

  • 在基于浏览器的游戏中?没有。
  • 在典型的PC游戏中?没有。(但是您可能会在低级库中看到一些。)
  • 在iOS和Android游戏中?没有。
  • “ AAA” PC游戏和主机游戏?可能是代码库的一点,也许是0.05%。(库中还有更多内容。)

汇编语言知识在游戏行业中并不适用,但是取决于您制作的游戏类型,它可能会有所优势。

曾经有一个论点认为,与人工编写汇编程序相比,编译器在优化C代码方面做得更好。通常这是正确的,有时是错误的。但是,如今,不断增加的CPU复杂性和扩展“扩展”(即分离处理器)的需求相结合,意味着优化工作通常花费在其他地方。

近年来,我唯一一次在游戏代码中看到汇编__asm int 3语言是强制设置断点的语句,而我个人唯一的汇编语言用途是查看功能的反汇编以诊断异常的崩溃错误。


1
关于SSE指令呢?
军团再临》

4
@Legion,人们通常使用内在函数或包装SSE内容的数学库来编写SSE代码,或者使用专门设计为编译成SSE的专用迷你语言(例如ispc)编写SSE 代码。直接编写汇编仍然很少见。
内森·里德

1
关于iOS游戏:如果我没记错的话,3D / Math库Oolong使用了一些嵌入式ARM程序集。自从Apple发布Accelerate框架以来,就不再需要此功能。
Nicolas Miari 2012年

同意内森(Nathan)-SSE和类似的针对特定指令的优化通常存在于库中(因为它们通常是唯一可以获得最大收益值得付出努力的地方)。
Kylotan

26

现代控制台游戏中的大量高性能代码是使用汇编和C ++之间的某种中间立场编写的:编译器内在函数。这些构造看起来和解析都像C ++函数,但实际上被翻译成单机器指令。因此,例如,我的“将向量V的每个值钳位为> = a和<= b”的函数看起来像

// for each v.x, ensure v.x >= a.x && v.x <= b.x
inline __m128 ClampSIMD( const __m128 &v, const __m128 & a, const __m128 & b )
{
    return _mm_max_ps( a, _mm_min_ps( v, b ) );
}

在这样的函数中,我仍在考虑特定的机器指令,但是我很方便用C编写它们,因此我不必担心寄存器着色和调度以及加载操作和其他无聊的细节。

您仍然需要知道CPU支持的指令,特别是因为与聪明人的工作能力相比,现代编译器在矢量化代码方面很糟糕。有时,关于如何安排代码的细微细节可能会对性能产生巨大影响,而如果不了解机器的运行情况,这些影响就不会很明显。

尽管我们可能没有在汇编中编写代码,但仍然在汇编中进行了大量调试。优化编译器会以调试器无法跟上的方式积极地重组代码,因此通常在调试“发布模式”时,最好的方法是弹出反汇编程序并以这种方式跟踪代码。GDC关于崩溃的“取证调试”演讲说明了在该级别进行调试的许多原因和方式。


3
+1仅仅是因为Crashworks在SO上广为人知就是“那个为游戏编写真正的底层优化代码的 -如果有人知道这个话题,就是他。
BlueRaja-Danny Pflughoeft

@ BlueRaja-DannyPflughoeft“众所周知”吗?我受宠若惊!=)根据内森·里德(Nathan Reed)的评论,一个有趣的巧合是,我在淘气狗中学到了许多低级优化技能。
Crashworks

在其他地方,我也听说过汇编在调试中的重要性。因此,我将学习它。感谢您的见解和链接。
军团再临》

7

过去需要手动卷装的问题越来越少。您“可能”获得的速度会增加可读性和调试能力。还应该仅将其作为代码部分的最后优化步骤之一,因为在大多数情况下,汇编并不能解决速度问题。如今,CPU的速度越来越快,而内存速度却没有,通常,控制数据流过CPU的方式比其他任何方式都更为重要。

对于现代编译器,他们还发现很难对汇编代码进行优化,因为它们必须处理您所碰到的所有寄存器,而且通常无法在手工编写的代码中对指令进行重新排序。为了减少对汇编的需求,现在还提供了一些内在函数,这些内在函数有助于访问低级概念,但是这种方式对编译器友好,并允许它们与您一起工作而不是反对。

随着中说,在PS3的SPU是一个人们仍然有作为解释使用汇编来获得最大的处理器,具有手动指令流水线例如面积这里


1
即使在PS3上,人们通常也不是完全裸露地编写程序。有一个工具可以让您以类似于汇编的语法编写代码,在其中指定机器指令,但是它可以为您执行寄存器分配,指令调度和循环流水线操作。好吧,也许Naughty Dog确实可以手动完成所有操作,但是就我的经验而言,即使是大多数PS3 SPU开发人员也没有。:)
内森·里德

1
@NathanReed在PS2时代,手动循环流水实际上是Naughty Dog程序员采访的一部分。
Crashworks

-1

事实是,我们生活在一个多平台的世界中,我们的游戏代码的某些部分必须针对本地平台进行量身定制-不一定非要这样做,但是如果我们利用本地硬件的话就会有好处!

这不关乎游戏或游戏逻辑,而是关乎硬件局部性,以使游戏逻辑所依赖的代码达到最佳性能,我们确实可以包装代码段,例如使用宏,这样只有一个源代码可以很好地执行。所针对的平台。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.