2.2.2 计算性能优化
前面提到,阵营视野数组的计算与更新需要以同阵营探索源为单位依次计算,单次更新的探索源数量决定了计算效率,因此可以通过对游戏对象分帧更新来降低更新频率,一些移速慢的角色或者小兵、野怪可用较慢的频率更新,而对抗激烈、位置变化频繁的英雄则以较高频率正常更新。除此之外,可以通过减少有效探索源数量来提升计算效率,例如已经死亡的单位或被技能致盲的单位不再被当作有效探索源。
除探索源数量的限制,2.1.2节提到,我们需要根据角色的不同视野范围来动态计算视野范围图,因为角色可能在对局中发生视野范围变化。而在运行时动态计算视野范围图有一定的计算性能消耗,且视野范围越大消耗越大,但不同角色之间相同的视野范围图并无差异,因此可以使用Map结构对计算出来的数据进行缓存从而避免多次计算。其中,Key代表视野范围,Value则是实际的视野范围图。进一步地,可以在游戏的加载阶段(Loading)提前预创建常用视野范围图并使用Map结构将其缓存起来,运行时则可直接从缓存中读取,避免了运行时的计算,从而提高计算性能。
对局中还有一些静态建筑物等角色,比如防御塔,虽然有视野探索功能,但其位置不会发生变化,因此不需要实时更新,可以对其它们做分离。它们的视野更新是由状态变化按需更新的,例如仅在出生、死亡时对其范围内阵营视野数据进行处理。需要注意的是,由于优化掉了静态单位的视野实时更新,由静态角色点亮的网格不能够进行视野残留衰减,否则将失去其点亮功能,因此需要标识出由静态角色点亮的可见性数据,标识方法可以使用一些特殊点亮值(如8位0xff)代表由静态角色点亮的视野网格。
在整个视野更新流程中,探索源最终可见区域的计算与阵营视野数组点亮数值的赋值是运算消耗最大的部分,其本质上是两张图的处理与赋值,如图2.18所示。CPU处理大量数据时,速度的主要瓶颈是指令数,减少指令数就会提高计算性能。在数据量固定的情况下,单条指令能够处理的数据数量决定了指令数的多少,而SIMD(Single Instruction Multiple Data)技术可以让CPU同时处理多个数据,因此对大量数据的处理速度比常规的SISD(Single Instruction Single Data)快。SIMD常用于图像、音频领域的向量、矩阵等大规模数据运算。以NEON[5]为例,它是基于ARM架构处理器设计的SIMD指令集,ARMv8中的NEON单元可使用128位的寄存器进行运算,并且可以根据需要按不同大小进行分组(Lanes)。如图2.18所示,4条SISD的ARM64运算指令可以使用一条SIMD指令代替,128位的寄存器被分成4个32位Lanes并同时进行与运算(AND Operation),然后将最终结果储存至目标寄存器。因此,另一优化点是,使用SIMD指令集进行阵营视野可见性数组的计算与更新,通过SIMD指令集的使用可以有效减少计算最终可见区域及视野残留赋值的指令数。
图2.18 SIMD优化