

游戏性能优化杂谈(四)
source link: https://zhuanlan.zhihu.com/p/268425759
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

对于当代游戏,尤其是大制作来说,IO往往是一个非常主要的性能瓶颈。不仅仅是CPU读取游戏资源的方式,游戏资源的打包方式本身也会极大地影响CPU性能。
常规的文件操作,是一个多个步骤连锁的过程:需要按层级遍历目录,需要对比文件名,需要打开文件,而且这里面每个步骤往往都是一次系统调用。当代游戏的资源文件数常常都在数万至数十万这个数量等级,即便在一帧当中需要参照的资源很可能就数百上千,那么多文件每帧都去open-close一次显然是不聪明的。
事实上,游戏的资源文件一般只有游戏本身会去访问,而且是只读访问。它们在游戏的运行过程当中一般并不会发生任何更改,也不太需要诸如文件级别安全性、访问日志等功能。因此,通常的操作系统层面的文件和文件系统,对于游戏资源来说,是有些过于臃肿的。在文件系统所提供的众多功能当中,游戏资源文件所需要的,其实只是:能找到,能读取。
所以,当代的游戏引擎一般都会对零散的资源进行某种形式的归档,将这些零散的资源组织在一个或者数个大文件当中,这样可以大大减少文件的总数,从而减少需要open-close的文件数,并且避免各种不必要的文件系统开销,提高文件访问性能。
不过,这种方法的采用同时也带来了新的问题:如何有效地在归档文件当中组织资源。也就是,要创建多少个归档文件,每个文件当中要包括哪些资源,这些资源在归档文件当中应该如何排列,如何在读取的时候实现快速定位的问题。
同时,我们甚至还需要考虑游戏版本打补丁的时候,补丁大小的问题。如果归档文件很大,那么对其进行的一点点改变,比如替换其中一个资源,都有可能导致很大的补丁。
对于传统的线性流程游戏或者关卡式游戏,资源间的关系比较一目了览,引擎可以直接按照关卡或者游戏故事推进的方向组织资源。
但是在开放世界游戏当中,或者说非线性流程游戏当中,资源间的关系就变得更加复杂了。通常最容易想到的是按照地图分块来组织,但是这对于静态的资源还相对容易(但是依然有重复资源以及跨分块资源如何归属的问题),对于动态资源则更加难以按此处理。
所以对于这种情况我们往往需要将资源分别组织在不同的层面(地图)上,各自依据其特性进行不同的管理。
当然,这个问题还远不止如此。我们还需要考虑游戏内容制作上的便利。我们不能因为性能上的各种考虑导致美术要改个素材需要重复改很多拷贝或者变种。而实现这个,需要建立一条完整的内容生产流水线,包括很多内容制作工具的插件,也包括资源管理数据库、自动构建服务器、以及各种调试测试工具。
Recommend
-
38
最近一年一直在为PS5发售进行软件方面的准备,所以文章写得很少了,大部分时候都只是在知乎上灌水调剂一下心情。 其实日常工作当中,除了诸多杂事之外,比较整块的主要是两部分: 向国内签约厂商宣讲最新的...
-
24
上一篇提到优化的第二个标准:CPU执行周期,但是没有解释什么是CPU执行周期。 其实CPU执行周期就是游戏主循环循环一次。往往,对于当今大部分游戏引擎,这也代表读入了一次用户输入,执行了一遍游戏逻辑,输出了一帧游戏画面。 ...
-
27
在一个CPU周期当中,通常诸如读取用户输入、执行引擎内部逻辑这些引擎固有的功能,开销一般是非常稳定的。而诸如执行游戏逻辑(脚本)、调度资源、网络通信、生成渲染命令这些,是容易发生变化的。 其中,资源的调度和网...
-
27
在当代游戏引擎当中,CPU负责生成GPU命令队列,并提交给GPU执行。因为这个命令队列是生成在内存空间当中然后提交给GPU的,所以无论对于CPU还是GPU来说,这其实也是一种IO操作。 特别是,在PC等通用环境下,为了提高系统的鲁棒性和兼容性...
-
17
游戏逻辑的执行,也是CPU端性能瓶颈的常见原因之一。 当代游戏引擎的一大进步,是将游戏逻辑的制作从程序员手中解放出来。WYSIWYG的可视化编辑,基于脚本语言甚至是节点连线的二次开发,都大大降低了编写游戏逻辑的技术门槛。但是正如老...
-
24
我认为性能优化可以分为宏观层面的优化,与微观层面的优化。前者多与开发技术及流程的选型有关,因此应该在项目的前期就开始考虑,而且是越早考虑费用效益比越好。而后者则是对于成品性能热点区域针对性的优化,通常在项目的中后期进行,且效果...
-
45
GPU管线的最前端通常是一个指令获取与译码单元。这个单元从内存取出CPU传递过来的指令,将其进行译码。一些命令发送给后面的微核心进行执行,比如DMA数据传输、和CPU之间的通信同步等等;另外一些命令则对GPU内的数百个状态寄存器...
-
37
VS之后,是光栅化阶段。这个阶段属于固定功能(不可编程)阶段,通常被认为是执行效率很高的,所以往往会被忽视。 其实就我所观察到的情况来言,这部分成为瓶颈的情况,并不罕见。比如《原神》在开发过程当中,就出现过这样的情况。...
-
39
GPU的光栅化模块之后,是一个工作量打包模块。这个模块负责将光栅化的结果(fragment)按照一定大小(N卡:warp32,A卡:wavefront64或wavefront32)打包,然后交给下面的处理阶段(PS) 这里需要注意的一个细节是,离散化的粒度虽然最...
-
20
光栅化的另外一个常见的性能问题在于保序。 我们都知道,Z测试(也就是深度测试)的引进将画面绘制顺序解放了出来,也就是我们可以以任意顺序绘制画面但是得到相同的结果。 但是现实是这只对于完全不透明的场景对象有效。况且,...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK