在WebGL 平台上的Unity 性能基准
Unity即将大力支持的一个令人振奋的新平台是WebGL。当我们将Unity项目移植到这个新平台时,一个关键问题是明确其在该平台上的性能表现,以及探索如何让性能达到最优。
WebGL性能的特殊性
在性能方面,WebGL具有独特性,原因如下:
- 所有代码都需交叉编译为JavaScript。
- 一些常见的性能增强技术,如多线程和SIMD(单指令流多数据流),目前暂不支持。
- 依靠全新的脚本库IL2Cpp来运行用户的脚本。
因此,我们需要探究的问题包括:对于游戏游玩而言,其效率是否足够快?在不同的浏览器和硬件环境下,性能表现如何比较?什么样的编译设置能生成最高效的结果?
我们自己也曾无数次思考这些问题,而且用户和供应商也经常询问我们关于WebGL的实现进展。最直接的方法是在WebGL中运行Unity的现有内容并监测帧率。我们发现,大部分测试内容的帧率至少能达到本地编译的50%(这受多种因素影响,如所使用的浏览器)。你可以测试这里提供的两个游戏Demo。
然而,我们需要精准可靠的数据。具体来说,哪些模块在WebGL中运行特别慢,哪些比较快,不同实现方式之间的确切区别是什么?
Unity Benchmarks的创建
为了找到答案,我们创建了Unity Benchmarks,这是一套在Unity中编写的基准测试用例。这些测试用例聚焦于引擎的不同功能,并生成易于比较的性能数据。点击此链接,在你的浏览器中运行WebGL中的Unity Benchmarks吧!(注意,一些WebGL实现在Windows系统中关于Mandelbrot GPU benchmark(曼德勃罗GPU基准)这项,可能会产生不正确的结果,这是因为它们渲染shader的方式有误。我们正在研究该问题并努力寻找解决方案。)
物理性能基准测试
Unity Benchmarks包含针对3D物理、2D物理、粒子、导航、动画和蒙皮、初始化对象、脚本、draw calls和GPU像素处理的不同测试用例。每个测试用例都会计算在固定时间内Unity能重复执行给定任务的次数。对于生成的数据,数值越大表示性能越好。
如果运行所有基准测试,会得到一个总分数。该分数是所有基准测试分数的加权总和。由于不同基准测试的结果差异较大,所以在总分中它们的权重不同。该权重是根据WebGL中测试机器生成的近似结果校准的,但这种校准有一定的随意性。因此,在比较结果时,各项测试的单独分数比总分更有价值!
以下是一些测试结果(所有基准测试均在15寸Retina屏的MacBook Pro上运行,CPU为2.6GHz的i7内核,操作系统为OS X 10.10):
为了更方便地显示图表,这些分数都进行了等比例缩放,以FireFox的分数为1.0。分数越高表示性能越好。
观察结果
- 浏览器性能对比:在大多数基准测试中,Firefox使用的asm.js在几乎所有测试项上都比Chrome和Safari更快,它是目前运行Unity WebGL内容的最佳浏览器。我们期待在不久的将来,asm.js能在其他浏览器中也得到支持。
- GPU性能瓶颈情况:如果程序主要受GPU性能瓶颈(GPU-bound)的限制,那么WebGL的性能将非常接近本地代码。
- 脚本性能优势:在某些情况下,WebGL的效率实际上会显著高于本地代码。这主要针对那些大量依赖脚本性能的测试用例(如Mandelbrot和CryptoHash,它们的算法均使用C#实现),因为IL2Cpp可以生成更优化的代码(想了解更多,请关注即将发布的另一篇博文)。
- 多线程和SIMD的影响:在一些经过大量优化、使用多线程和(或)SIMD的场景下,本地代码的效率仍能比WebGL高出好几倍,例如3D物理测试(Unity 5中的PhysX 3.3完全支持多线程)。相比之下,2D物理测试在Firefox和本地代码中的效率较为接近(Box2D不支持多线程)。我们期望在不久的将来,JavaScript能支持SIMD和多线程,这可能会改变当前的情况。
总体而言,尽管WebGL在某些方面明显比本地代码慢,但整体性能已经相当不错,并且未来有望进一步提升。我们希望这些基准测试用例能帮助那些希望优化自己的JS引擎和WebGL实现,从而高效运行Unity内容的开发者。