一个小的“突击队”来优化Unity渲染的CPU

一个小的“突击队”来优化Unity渲染的CPU

在工作中,我们构建了一个小型“突击队”来优化 Unity 渲染的 CPU。 我会在博客上写下我所做的部分(似乎是公认的做法),我不知道我要去哪里,但这就是乐趣的一部分!

背景/基本提醒 我会在很多场合严厉地说“这段代码糟透了”! 当试图改进代码时,当然要改进不好的部分,所以这部分通常是重点。 但这并不意味着代码库总体上很糟糕,或者该代码不能永远使用! ! 就在今年 3 月,我们还推出了《永恒之柱》、《Orian 与盲目森林》和《城市:天际线》,这些都是高度评价的 PC 游戏,都是用 Unity 制作的。 对于“仅限原型设计的终端设备”来说还不错。

事实上,任何一段经过长期开发并经过某些人的代码,在某种意义上都容易出现“坏”的情况。 有些地方的代码很奇怪,有些地方没人记得代码是如何工作的以及为什么工作。 许多年前做出的一些决定不再有意义,而且没有人有时间修复它们。 在一个足够大的代码库中,任何一个人都无法完全理解所有代码的工作细节,一些决定会以微妙的方式与其他决定发生冲突。 用某人的话说:“有些代码库很糟糕,有些代码库没有”:)。 但是尝试改进代码库非常重要! 永远精益求精。 我们在各个方面都做了很多改进,但坦率地说,渲染代码在过去几年里已经取得了长足的进步,但没有人从整体上好好审视代码并将其作为一个整体进行改进全职工作代码。 我们是时候这样做了! 很多次我会指着一些代码说,“哈哈!那太蠢了!” 我首先编写了该代码。 也许我现在理解得更好了,或者那些代码在当时是有意义的,或者那些代码考虑了各种因素(比如赶时间)是有意义的,或者也许我当时只是愚蠢。 也许五年后当我查看我当前的代码时,我会说同样的话。

不管怎样……

愿望清单在图中,这就是我们想要实现的最终目标——一个运行无瓶颈的高吞吐渲染系统。

unity 序列化什么意思_unity中序列化雨松_国民教育序列大学本科是什么意思

除了这张图,这里的“它是什么”部分几乎完全取自我们的工作 wiki:

当前用于渲染(Unity 5.0)、着色器运行时和图形 API 的 CPU 代码“效率不高”,它存在一些问题,我们希望尽可能多地处理它们:

GfxDevice(我们的 API 概述):该概述主要围绕 DX9 概念设计,部分围绕 DX10 设计。 例如:常数/统一缓冲区现在是不可能的。 多年来有机增长的“烂摊子”,有整理的余地。

现代 API(如控制台、DX12、Metal 或 Vulkan)允许并行创建命令缓冲区。

渲染循环:有许多小的低效和冗余决策需要优化。 在可能的情况下使用本机命令缓冲区创建 API,并行运行循环的一部分unity 序列化什么意思,和/或完成作业的一部分。 让代码更简单、更统一,提取相同的功能,让代码更易测试。

着色器/材质运行时:内存中的数据布局“不是很好”。 代码很复杂,我想整理一下,让代码更容易测试。 “固定功能着色器”的概念在运行时不应该存在,参见[Generate fixed-function shaders on import]。 基于文本的着色器格式很傻游戏角色,请参阅 [Binary Shader Serialization]。

约束 无论我们想做什么来优化/清理代码,我们都应该尽量让功能发挥作用。 一些很少使用的功能或极端情况可能会被更改或破坏,但这是最后的手段。

同时,程序员需要考虑一些代码是否看起来很复杂,这可能是由多种原因造成的,其中之一是“有人写了太复杂的代码”(太棒了!简化它!); 由于某些原因,这段代码很复杂,但现在不再复杂了”(太棒了!简化它!)。

但也有可能代码正在做复杂的事情,例如:它需要处理一些棘手的情况。 也许代码可以简化,但也有可能不能。 “从头开始重写东西”很诱人,但在某些情况下,当您开始做与旧代码相同的事情时,您新的、漂亮的代码可能会变得复杂。

如果有一段CPU代码,提高CPU性能有几个关键:1)“运行得更快” 2)“更好的并行性”。 我想我会首先关注“跑得更快”。 部分原因是我还想简化代码并记住代码所做的不同事情。 简化数据,让数据流更清晰,让代码更简单,往往也会让第二步(“更好的并行性”)更容易实现。

首先,我将研究更高级别的渲染逻辑(“渲染循环”)和着色器/材质运行时环境,但小组中的其他人将着眼于简化和绿色化渲染 API 抽象,然后遵循“并行性”更好”的方法。

为了测试渲染性能游戏开发素材,我们需要一些真实的内容来测试。 我看过我们拥有的几个游戏和示例项目unity 序列化什么意思,并使它们受 CPU 限制(通过减少 GPU 负载 - 以低分辨率渲染;减少多边形参数;降低阴影贴图分辨率;减少或删除后期处理步骤;降低纹理分辨率)。 为了给 CPU 带来更高的负载,我重复了场景部分,以便渲染对象比最初更多。

对于“嘿,我有这 100,000 个立方体”这样的例子,测试渲染性能很容易,但这不是一个非常现实的用例。 “许多对象只使用相同的材​​质”和数千种具有不同参数的材质、数百种不同的着色器、数十种渲染目标更改、阴影贴图和常规渲染、alpha 混合对象、动态生成的几何体渲染场景等。是不同的。

另一方面,测试“完整游戏”也很棘手,尤其是当游戏需要交互性、加载完成速度很慢,或者一开始不是 CPU 受限时。 测试 CPU 性能时,在多个设备上进行测试很有帮助。 我通常在 Windows 系统的开发 PC(目前是 Core i7 5820K)、Mac 系统的笔记本电脑(2013 rMBP)以及我手边的任何 iOS 设备(目前是 iPhone6)上进行测试。 在控制台上进行测试非常适合这项工作; 我一直听说他们有出色的基准测试工具、或多或少的固定时钟和相对低端的 CPU——但我手头没有任何开发包,也许我应该买一个。

笔记 接下来,我运行基准项目并观察分析器数据(Unity 分析器和第 3 方分析器,如 Sleepy/Instruments),同时我还观察代码以了解它在做什么。 这时候,每当看到奇怪的东西,我都会记录下来,作为以后研究的依据:

unity中序列化雨松_unity 序列化什么意思_国民教育序列大学本科是什么意思

上面的一些奇怪之处可能有合理的原因,在那些情况下我会添加代码注释,一些内容可能曾经有过原因,但不再合法。 在这两种情况下,源代码控制台日志记录/评论功能都会有所帮助,并且应该询问编写代码的人为什么代码是这样的。 上面列表的一般可能性是因为我多年前就是这样写的,这意味着我必须记住这些原因,即使它们“在当时看起来是个好主意”。

好吧,这就是介绍。 下次从“WAT”中提取一些东西? 上面列出来,尝试用它们做点什么吧!相关阅读:腾讯游戏开发者平台

unity中序列化雨松_unity 序列化什么意思_国民教育序列大学本科是什么意思