大多数游戏做多核优化的难点是什么?|环球快报

我来尝试一一解答,你的问题因为篇幅我稍作删减处理:

1:疑惑:我在玩很多游戏的时候,发现游戏本身对GPU占用不是很高,很多都是依赖CPU进行处理,但是这些游戏对CPU利用率非常的低(通常都是单线程)。


【资料图】

题主你提到的游戏我虽然都没玩过(因为工作原因现在很少有时间玩游戏),但我还是搜索了一下你说的这几个游戏,她们的画面是这样的(YouTube截图):

Hearts of Iron 4 钢铁雄心4
Rimworld 环世界
Prison Architect 监狱设计师

看到这里相信已经很明显为什么她们的GPU占用率很低了:因为绘制简单。其实CPU和GPU本质上都是获取指令,获取数据,执行指令计算,存储计算结果,画面简单自然计算量低,计算量低以现代的GPU瞬间就算完了,自然占用率低。

AAA大作里通常都是相反的,一般都是GPU是瓶颈。主要原因有两点,其一是图形复杂,其二是其实现在的GPU因为其优秀的并行特性还承载了很多非图形的计算工作,比较流行的大概有在compute shader里做模型的skinning,布料动态模拟,甚至一些AI逻辑。

2:提问:为什么有些厂商在做游戏时候不做多线程/多核优化?这是一件很困难的事情么?

恰恰相反,现在CPU的多线程并行计算在游戏引擎里已经非常普遍了,区别不在于有没有,而在于各团队做到了一个什么程度

在这里无意展开,大概说一下游戏引擎里比较普遍的可以并行去做的系统:比如动画计算,物理引擎中有很大一部分可以并行,碰撞测试,粒子特效,等等等等。

至于难不难么,我认为要分两方面去看:

2.1:多线程系统的实现。这属于引擎底层核心,包括多线程的创建,管理,调度,debug等等方面。这一块必须必须由经验丰富,基础扎实,对自家引擎熟悉的老兵来把握,难度极高,新人做不来。但值得一提的是这种系统开发成本虽然高,但开发完成之后可以持续使用一两个世代。

2.2:多线程系统的应用。底层开发好之后,上层使用就简单多了,比如gameplay程序需要把游戏逻辑切成一块一块可以并行的小块,然后调用底层系统执行。说实话如果底层系统对使用者友善的话,应用起来不难,需要一段时间适应并行思维,但习惯了就好。

3:提问:如果要做多线程/多核优化,应当是怎么样的一种思路?

这个没有固定的方法,也没有绝对的对错,总的原则就是,慢了就想办法优化,从容易优化的地方入手,够用就好

从我使用过的3个AAA引擎来看,大概有两种思路吧:

3.1:Crystal Dynamics和Sledgehammer Games。一个是古墓丽影的引擎,一个是使命召唤的引擎,这两个引擎的实现是,把比较明显的,容易并行的地方做并行,剩下的在一个主线程内继续单线程运行

3.2:顽皮狗。顽皮狗的引擎在并行优化上做得是我见过最极致的引擎,使用的是比线程更轻量级的fiber,细节不展开说,主要思路是多核从一开始就并行,基本上不再存在主线程这个概念。当然了,因为计算任务和任务之间仍然存在依赖性因此等待是无法完全避免的,但并行程度一般来说比我接触过的其它引擎更好(还有更高级的多帧在时间上重叠也不展开说)。

这里给出一个顽皮狗引擎并行化的讲座链接,是我们其中一个技术总监讲的,内容很优秀:

Parallelizing the Naughty Dog Engine Using Fibers

4:提问:win10这部分(多线程)内容优化在哪里?

win10是操作系统,操作系统自身有任务调度和安排的功能,但跟前面说的引擎内并行优化是两码事,有兴趣你可以网上找找操作系统的入门知识介绍,这一块内容很深。

5:总结。

并行这东西说白了就是具体情况具体处理,因为大家的引擎架构,实现,计算需求都不同。如果有一个相对通用的底层系统当然很好,没有的话各厂商也把东西硬做出来了。并行是有代价的,所以计算任务的粒度(granularity)要把握好,否则可能得不偿失,最终目标是取得动态平衡,把你想要的效果在你想要的效率里实现出来。