作为一个专业web后端开发,非常业余游戏爱好者,普通硬件退烧者,虽然对游戏研发一窍不通,想对游戏性能的问题探讨下。
游戏性能与多核CPU的疑问
第一个问题,近几年为什么游戏主旋律都在GPU的选择上,而往往都是CPU能力过剩,难道CPU就没有压榨的空间?
先拿吃鸡游戏举例,引用一张评测文章里的CPU与显卡不同组合配置的大逃杀benchmark图:
可以看到搭载了GTX 1080+i5 7500(4核4线程 3.4GHz)的配置跑分比GTX1070+i7 7700k(4核8线程 4.2GHz)高,说明此配置中显卡仍是决定因素。
而使用的CPU 与 显卡的详细参数如下
游戏引擎
为什么会这样?先了解下常见的游戏引擎,有助于了解其中的原因。
我对游戏引擎不太了解,先找公开的资料。两大游戏引擎之一的Unity,代码开源,文档齐全,先从文档了解他涉及的功能。
- 2D
- Graphics
- Physics
- Scripting
- Multiplayer and Networking
- Audio
- Animation
- Timeline
- UI
- Navigation and Pathfinding
- Unity Services & Dashboard
- XR
- Open-source repositories
所以引擎包括了
2D : 顾名思义
图形: 主要有灯光,摄像机,材质,贴图。
物理: 主要控制游戏世界物体相关的交互,如碰撞。
脚本: 提供对引擎创建的游戏对象的控制,触发游戏事件,响应用户输入。
多人与网络: 提供对网络游戏支持。
音频: 音效必不可少,还提供声源定位等。
动画: 又是个无须解释的。
时间线: 常用来处理我们常说的过场动画。
UI: 定义游戏界面,玩家最长时间观看的地方。
导航与路径寻找: 定义游戏对象的导航点。
Unity服务&仪表板: 跟web后端一样,管理员的控制台,观看各种游戏数据。
XR: 提供VR/AR支持。
可以猜测游戏主入口的方法会加载以上功能组件,图形/物理/网络/脚本 层次上不相关,都可以在各自线程进行工作。
广义上的游戏,无论是单机游戏还是网络游戏,其主要的处理层面是在玩家与游戏中物理世界中各种事件的交互处理上。作为游戏效果的直接体现上,3D游戏中的贴图与实时多边形渲染是一个主要值得优化的性能点。
DirectX
DX12是随WIN10搭载的,针对现代多核CPU提供了优化。主要是下沉了API提供的基础功能,更贴近硬件,当然这样开发者需要管理更多的CPU与GPU的同步问题,以前在DX11中是隐含在runtime时进行处理的,DX12中对此的介绍:
图形渲染是现代3D游戏的主要任务之一。在DirectX 9中,原则上所有渲染API都必须在一个线程中调用。DirectX 10/11中加强了多线程支持,但各线程的负载很不平衡,渲染相关负载主要集中在游戏的主渲染线程和图形驱动中,这使得渲染任务无法充分利用现代多核处理器的能力,经常成为游戏渲染管线的主要性能瓶颈之一。
为了提高图形渲染效率,在DirectX 12中,多线程得到了前所未有的支持。在重新设计的DirectX 12中,为了让应用程序的图形渲染可以达到最大的多核CPU的使用效率:一方面,DirectX 12尽可能地预处理和复用渲染命令,降低渲染状态的切换开销,提升渲染API在CPU和GPU上的处理效率;另一方面,为应用程序提供了更高效的多线程渲染机制,允许应用程序最大程度地利用多任务获得性能提升。通过使用多线程手段可以使图形驱动在CPU端的开销降低,同时也使GPU的工作效率显著提升。DX12的多线程机制除了使渲染任务能更均衡地并行运行在不同的处理器核上以提升性能,还能降低CPU的功耗,这对移动平台上的游戏也非常重要。
从原文介绍可以看出,由于3D场景渲染工作是由CPU提交给GPU进行的,首先GPU要能在短时间内完成运算,在此基础上如果GPU有富裕,我们希望能让CPU开启多线程提交更多的任务给GPU进行运算。
据了解画图渲染的过程是程序向显卡提交一个Draw:App->DX runtime->User mode driver->dxgkrnl->Kernel mode driver->GPU ,到GPU前的工作量都在CPU, DX12的设计目的是减少中间层,提高效率。
基于此,参考以下使用了DX11与DX12的CPU负载对比图:
降低了单核CPU的负载,平摊了一部分任务到其他核上,比DX11时8核有2核完全没用上有改善。
看一下最近流行的吃鸡最低配置:
处理器:i3-4340 / AMD FX-6300
显卡:GeForce GTX 660 / Radeon HD 7850
DirectX : 11
DX11显然是个问题,软件总是落后于硬件更新的,硬件架构升级后,上层的操作系统才会开始适配,然后是操作系统之上,应用层的游戏引擎。
再看看DOTA2, 还在使用DirectX 9c。
游戏引擎需要使用操作系统提供的新的硬件层的抽象API,封装层高层API供开发者使用。
至少基于Unity3D的产品显然还没有升级。
显然与Web产品一样,JDK已经开始发布10了。还有大量的遗留产品在使用JDK6。JDK8的lambda使用方式也才刚刚开始普及,应用层比底层设施还是要迟缓的多。
参考内容:
https://msdn.microsoft.com/zh-cn/communitydocs/game-development/directx-12-white-paper/ta15073006