微观优化-BAD与游戏开发


12

在游戏开发中,商业应用程序C#中有很多C / C ++。我已经看到C / C ++开发人员对单行代码如何转换为汇编表达了担忧。在.NET中,很少有人进入IL。

在C#中,“微优化”被皱眉了,很少见并且通常是浪费时间。在游戏开发中似乎并非如此。

是什么造成了这种不一致?游戏会不断推动硬件极限吗?如果可以,随着硬件的改进,我们是否应该期望高级语言接管游戏产业?

我不是想就C#作为游戏开发者的可行性进行辩论。我知道它已经完成了一定程度。专注于微优化。具体来说,Game Dev与Applications dev之间的区别。


游戏更新我的意思是现代,大规模的发展。EG MMORPG,Xbox,PS3,Wii ...


3
我曾经担任过游戏开发人员和应用程序开发人员,两者之间的分歧是微不足道的。没有配置的微优化在这两者中都没有。许多游戏没有非常强大的要求,也不需要任何优化。与一般的60Hz游戏相比,某些业务应用程序要求的要求(例如,正常运行时间和实时保证)要严格得多。
Dave Hillier 2013年

1
一个额外的因素是,在业务应用程序中,您通常可以选择硬件(出于某种原因)。如果我需要更多处理能力,则可以购买另一台服务器,或者花更多时间在AWS上。在游戏中,需要最新的硬件才能将60美元的游戏变成1060美元的游戏和视频卡。如果您是为控制台开发的,那么升级硬件可能意味着要等几年才能等待下一代。如果无法获得更好的硬件,则必须更好地利用它。
安德鲁

Answers:


17

在业务应用程序中,CPU并不总是瓶颈。业务应用程序将花费大部分时间等待。例如:

  1. 等待数据库查询结果
  2. 等待Web请求完成
  3. 等待用户进行UI操作

这就是为什么优化处理性能的代码不会增加太多价值的原因。

主要考虑因素是:

  1. 上市时间
  2. 简单性,其他人可以理解和维护代码吗

6
我要指出的是,优化数据库查询的代码可以极大地提高业务应用程序的可用性。
HLGEM 2011年

4
+1。数据库和网络优化通常会为业务应用程序带来更多收益。例如,选择JSON与XML和调整数据库索引
Shamit Verma 2011年

2
+1,但您应该添加等式的另一面:游戏的流动性所依赖的“主循环”和游戏中的渲染使每微秒损失一个价值损失,因为质量是可以感知的和其他感官
克拉姆

1
说得好。确实,在完成业务应用程序和游戏开发之后,我花了一些时间研究复杂的SQL查询,以期提高性能,这与花时间研究游戏的内循环一样。
2011年

一切归结为过早的优化是万恶之源。分析清楚地表明,在一般业务应用程序中花费的大部分时间是网络+数据库IO。
亚历克斯·雷肯

13

在业务应用程序中,微秒级的问题非常罕见。在游戏中,这是生活中的事实。

如果您想让游戏以每秒60帧的速度运行,则您需要约16.67毫秒的时间来完成该帧所需的所有操作-输入,物理,游戏逻辑,音频,联网,AI,渲染等;如果幸运的话,您将以30 fps的速度运行,并拥有33.3毫秒的豪华时间。如果框架花费的时间太长,您的评论就会受到影响,您的播放器将在网络论坛上充斥胆汁,您可能不会卖出尽可能多的东西(更不用说对职业自豪感的打击了),如果您真的很不幸,将找到您的团队为商业应用编写代码。

当然,游戏开发人员不必担心每条线,因为凭借经验和良好的分析器,您会了解哪些线需要担心。另一方面,这些担忧有时会触及在商业世界中可能被视为纳米优化而非微观优化的事物。

在提供可比且可预测的性能之前,不要指望任何高级语言能使C ++脱颖而出。


8
在高频交易应用中,微秒非常重要!
quant_dev

2
@quant:与大多数流处理应用程序一样-机器人技术,电网,火箭技术,医疗技术等。积压的积压过多,到赶上时机可能为时已晚。
亚伦诺特,2011年

@quant_dev:高频交易应用程序非常罕见的。
molbdnilo 2011年

不再。它们比会计应用程序稀少,但比飞机设计软件更普遍。
–quant_dev

微秒级在业务应用程序中也很重要,瓶颈通常在其他地方(整个网络,数据库或文件系统中)都可以找到。
RubberDuck

9

好的,因此您已经看到C和C ++开发人员沉迷于个别行。我敢打赌他们不会迷恋每一行。

在某些情况下,您需要最大的性能,其中包括很多游戏。游戏一直试图突破性能极限,以便在相同硬件上看起来比竞争对手更好。这意味着您将应用所有常用的优化技术。从算法和数据结构开始,然后从那里开始。通过使用事件探查器,可以找到花费最多时间的位置,以及通过微优化几条线来获得显着收益的位置。

这不是因为语言迫使人们加入其中,而是人们根据自己的意愿选择语言。如果您想浪费程序的最后一点性能,就不会编写C#并编译到CLR并希望JIT编译器(或其他任何方式)能很好地完成工作,而是在可以很大程度上控制的地方编写它输出。您将使用C或C ++(可能是C ++的受限子集)并研究汇编语言输出和分析器结果。

只要使用C和C ++的速度足够快,很多人就不必担心翻译的细节。


7

游戏会不断推动硬件极限吗?

是的,他们有。

如果可以,随着硬件的改进,我们是否应该期望高级语言接管游戏产业?

并非完全如此-因为随着硬件的改进,消费者期望游戏也会有所改进。他们不希望看到相同质量的游戏能更有效地开发,因为开发人员使用的是高级语言。他们希望每个新平台都能吹牛。

当然,有一些运动。当我还是一个小伙子并且首先对游戏开发感兴趣时,它就是手写的汇编,否则就该死了。那是Commodore 64时代。当然,如今,C ++是大多数游戏开发的通用语言。实际上,我们甚至已经看到了使用C ++编写引擎代码和使用高级脚本语言编写游戏逻辑代码的趋势。例如LUA,或者虚幻引擎具有自己的UnrealScript语言。


1
如今,大部分游戏开发人员+1都是使用别人编写的超优化引擎层,然后使用Python之类的工具或不太精巧的C ++将事物包装在一起。
Morgan Herlocker 2011年

需要注意的是,虚幻引擎现在已经将其脚本“向后”,从虚幻脚本转移到了C ++。对于现代C ++来说,这是一件很棒的事情,它允许您编写微优化的低延迟代码和简洁的高级逻辑。大多数其他语言只能通过牺牲延迟和性能来达到高级。
左右左转

7

在C#中,“微优化”被皱眉了,很少见并且通常是浪费时间。在游戏开发中似乎并非如此。

如果您仅可以使用高级代码和库代码来组装应用程序,请确保这是浪费时间。在这种情况下,请使用解释性语言编写。不会有太大的变化。如果您尝试实现尖端的全局照明引擎,该引擎可以像CryEngine 3一样实时实时动态地动态化动态场景内容,那么您自然就无法摆脱微优化的需求。


0

“游戏”是一个笼统的术语。如果您拥有MMORPG,则较小的优化会影响许多玩家。

玩家曾经并且可能一直习惯于实时实时地进行相对大量的事情。当然; 一次,拥有响应能力的Pacman或Tetris是目标。但是他们仍然必须做出回应。如今,通过丢包网络连接的3DMMORPG。

我肯定知道要乐观。



0

我总是发现“微观优化”这个术语比较模棱两可。如果对内存布局和访问模式的某些指令级更改使专业人员在不降低算法复杂性的情况下测量热点的速度提高了80倍,这是否是“微优化”?对我来说,这是一种“超级优化”,可以使实际用例的速度提高80倍。人们倾向于谈论这些事情,例如这种优化具有微观效果。

我不再在gamedev中工作,但在VFX中工作,例如路径跟踪,而且我已经看到许多BVH和KD树的实现,它们在复杂场景中每秒处理约50万条光线(多线程评估)。粗略地说,即使使用多线程评估,我也倾向于在光线跟踪环境中以低于100万条光线/秒的速度直接实现BVH。除Embree的BVH可以使用相同硬件在同一场景上处理超过1亿条射线外。

这完全归因于Embree的“微优化”速度提高了200倍(相同的算法和数据结构),但之所以如此之快,是因为其背后的Intel开发人员都是专业人士,他们依靠自己的分析器和测量工具以及真正调整了重要的领域。他们并没有凭直觉改变代码,而是做出了使0.000000001%的改进以显着降低可维护性为代价的更改。这些都是明智地运用到的非常精确的优化-在焦点方面可能是微观的,在效果方面是宏观的。

自然地,根据游戏对实时帧速率的要求,取决于您使用游戏引擎的高低级别(即使使用UE 4制作的游戏也经常至少部分以高级脚本实现,但不是说物理引擎的最关键部分),微优化在某些领域已成为实际需求。

每天围绕着我们的另一个非常基本的领域是图像处理,例如实时模糊高分辨率图像,以及作为过渡的一部分,可能对它们进行其他处理,我们可能已经在某处看到了过渡,甚至可能是操作系统的影响。您不必从头开始遍历图像的所有像素就可以实现此类图像操作,而不必以匹配的帧速率获得这种实时结果。如果是CPU,我们通常是在看SIMD和一些微调,或者是在看GPU着色器,这往往需要一种微层次的思维方式才能有效地编写。

如果可以,随着硬件的改进,我们是否应该期望高级语言接管游戏产业?

我相当怀疑仅凭硬件的进步就能做到这一点,因为随着硬件的进步,指令和技术(例如:GPU上的物理原理),技术以及客户对他们希望看到的产品和竞争的期望也同样如此。经常使开发人员再次进入低级状态的方式,例如现在Web开发人员在WebGL中编写低级GLSL着色器的情况(这种特定类型的Web开发可以说比十年或两年前更低,因为GLSL是一种极为底层的C语言,而且我从未想过十年或两年前,某些Web开发人员会接受编写此类底层GPU着色器)。

如果要有一种将性能至关重要的领域转移到高级语言的方法,那么它将必须更多地来自于我所看到的软件,编译器和工具。在任何可预见的将来,对我而言,问题都不在于硬件功能不够强大。它与我们如何在每次变化和前进时都无法找到最有效地与之交谈的方式有关,而又没有重新回到自己的语言的方式。正如我所看到的,实际上是硬件的快速变化使高级编程在这些领域变得难以捉摸,因为如果假设我们的硬件在接下来的几十年里不再突飞猛进,

有趣的是,这些天,当我在真正的性能至关重要的领域工作时,我不得不比起我开始时要低一些(即使我是在Borland Turbo C DOS时代开始的)。因为那时CPU缓存几乎不存在。它主要只是DRAM和寄存器,这意味着我可以将更多精力放在算法复杂性上,并以非常直接的方式编写链接结构(例如树),而不会影响性能。这些天,CPU缓存的低级细节几乎与算法本身一样主宰了我的思维。同样,我们拥有多核计算机,必须让我们考虑多线程,原子和互斥体以及线程安全性和并发数据结构等,在很多方面,我认为这是一个较低层次的关注点(如而不是像人类刚开始时那样直观)。

奇怪的是,现在对我来说这很真实。我认为,与30年前相比,今天我对硬件的底层和底层复杂性以及细节的影响更大,我正竭尽所能摘下怀旧眼镜。当然,我们可能在这里讨论了一些组装问题,并且不得不处理一些复杂的细节,例如XMS / EMS。但是在大多数情况下,我会说当时需要的复杂性,硬件和编译器意识要比今天在关键性能领域工作时要少。如果我们撇开写作不谈,这对整个行业来说几乎都是正确的。if/else 以更易于理解的方式进行声明,并考虑目前有多少人在思考硬件的底层细节(从多核到GPU到SIMD到CPU缓存,以及它们的编译器/解释器/库工作等等)。

高级别!=效率较低

回到这个问题:

如果可以,随着硬件的改进,我们是否应该期望高级语言接管游戏产业?

对我来说,这与硬件无关。这是关于优化器和工具的。当我开始时,人们几乎都是用汇编语言编写所有的主机游戏,并且当时确实具有性能上的优势,尤其是在缺乏生成6502的高质量编译器的情况下。

随着优化的C编译器在优化过程中变得越来越聪明,然后他们开始达到用C编写的高级代码与之抗衡的地步,有时甚至在许多领域甚至胜过了最优秀的汇编专家编写的代码(尽管并非总是如此),并且因此,至少在游戏的大部分编码中采用C无疑是一件容易的事。C ++在某个时候逐渐发生了类似的变化。C ++的采用速度较慢,因为我认为从汇编到C的生产力提升可能会完全由完全用ASM编写非平凡游戏的游戏开发者达成一致的共识,而不是从C转向C ++。

但是这些转变并不是来自硬件变得如此强大,而是因为这些语言的优化器在很大程度上降低了底层语言的水平(尽管并非总是如此,有些情况并不明显)已经过时了。

如果您可以想象一个假设的场景,我们可以用可以想象的最高级别的代码编写代码,而不用担心多线程或GPU或缓存未命中之类的问题(甚至可能不是特定的数据结构),并且优化器就像人工智能聪明,可以找出最有效的内存布局来重新排列和压缩我们的数据,找出它可以在此处和那里使用一些GPU,在此处和那里并行使用一些代码,使用一些SIMD,也许自己配置一下,并像人类一样继续优化其IR确实对探查器热点做出了响应,并且以超过全球最优秀专家的方式做到了这一点,那么即使是那些对性能至关重要的领域的工作人员也可以毫不费力地采用它...这是一个进步来自可笑的智能优化器,而不是更快的硬件。


0

在C#中,“微优化”被皱眉了,很少见并且通常是浪费时间。在游戏开发中似乎并非如此。

您在这里遇到术语问题。您正确使用了这些词,但是游戏开发人员和商人却以两种截然不同的方式使用同一术语。

对于企业而言,“微优化”意味着在由软件实现的整个业务流程中加快很小的一步。它被皱眉的原因通常是以下之一:

  1. 为实现相同的业务价值而花费的额外资金,速度要快几秒钟。速度改进中节省的资金来自不同的资金池(用户的时间),因此业务通常不会从花费的精力中受益,客户却会以牺牲业务为代价。
  2. 通常,业务程序员在整个业务流程中的可视性很差,因此优化单个步骤可能不会给整个流程带来良好的收益。例如,如果使流程的3%快10倍,则整个流程的速度提高了2.7%。
  3. 通常,企业拥有大量具有一定业务价值的剩余工作清单,并且会优先考虑添加该价值,而不是在(可能)更短的时间内交付相同的价值。

游戏开发是另一种野兽。“微优化”可以节省函数或例程中的少量时间。

  1. 游戏系统倾向于保持渲染周期。当前,黄金标准是每秒60帧,因此需要完成的所有操作都需要在1/60秒内完成并将其呈现到屏幕上。
  2. 这意味着在一个游戏过程中,相同的例程常常被调用成千上万。因此,将单个功能的10倍改进的价值放大了可以感受到改进好处的次数。
  3. 无法达到渲染速度会影响游戏的呈现。视频将变得断断续续,角色将以跳跃和跳跃而不是流畅的动作进行动画处理。这立即使玩家脱离了游戏的沉浸感,并进入了质疑游戏价值的领域。

因此,在业务中,没有人关心4步业务流程的形式是在0.6秒还是0.5秒内出现。在游戏中,人们会在乎是否可以将耗时200ms的例程减少到100ms内执行。

这一切与交付给客户的价值,客户的需求以及变更的成本效益比有关。


-1

这与为什么为特定工作选择该工具有关。

高尔夫球手会沉迷于推杆施加的方向和力,而在使用发球杆时不会那么多。

为什么?因为它们是不同的镜头。对于驱动器,您希望以最大距离使其进入球道。对于推杆,您想准确地将其插入孔中。

此处同样适用。游戏开发人员之所以选择C ++,是因为它使他们能够控制不同操作的性能。如果您选择了它,那么您将想要利用它。


-3

大多数业务应用程序是作为内部工具编写的。对这种工具的可用性的期望远低于销售给广大客户的软件。内部业务应用程序通常具有菜单和对话框,这些菜单和对话框对鼠标单击反应缓慢,窗口会延迟重绘,甚至是用Swing编写的GUI(恐怖!)。这是由于多种原因(最重要的是,该软件可自定义比其非常“时髦”,该软件的用户没有选择是否使用所涉及的软件,决定安装该软件请勿自行使用...)。所有这些的结果是,该工具的开发人员无需花费大量时间来优化应用程序的响应能力,但要特别注意功能的可扩展性和数量。不同的客户群=>不同的设计目标=>不同的方法。

请注意,针对大量受众的业务应用程序(例如Excel)进行了大幅优化。

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.