游戏开发46课 性能优化5

 

3. CPU优化

性能优化最主要的一部分工作是CPU,CPU性能优化好了,离目标就成功了一半。

3.1 缓存计算结果

缓存计算是空间换时间的经典应用,它适用于那些耗费大量CPU计算而计算结果无需每帧变化的逻辑。实现伪代码:

std::map<KeyType, ValueType> _cache;

ValueType Calculate(KeyType key)
{
    // 先尝试从缓存中获取结果,有就直接返回。
    if (_cache.count(key) > 0)
    {
        return _cache[key];
    }
    // 缓存不存在,执行真正的计算,并缓存计算结果。
    ValueType res = DoCalculation(key);
    _cache[key] = res;
    return res;
}

适用场景举例:

  • 复杂数学计算。Sin/Cos/Pow/Sqrt等运算要花费一定计算量,如果是第一次计算,可以将结果缓存起来,下次遇到相同的计算,直接从缓存中取值。
  • 物理模拟结果。物体的物理模拟过程耗费大量计算,但有些物体模拟完之后就处于静止状态,可以将它之前的模拟结果存下来,防止每帧更新计算。现代主流商业引擎都支持这种优化。
  • 光照贴图。光照贴图是离线将场景的静态光影计算并缓存成贴图,渲染时只需要采样光照贴图的颜色,极大降低了光照计算复杂度。
  • 搜索结果。例如场景节点搜索,场景节点一般采用树形结构,如果查找的节点很深,将显著增加遍历次数,此时很有必要将查找结果缓存起来。
  • 逻辑模块复杂的计算。游戏的逻辑模块,涉及到复杂的计算都可尝试用缓存法降低CPU负担。

3.2 预处理

缓存法利用空间换时间的思想,会增加内存开销;而预处理是将时间转移的思想,它并不会增加内存消耗。将需要花费大量时间加载或运算的逻辑,在启动程序后/加载场景时/切换界面前/进入战斗前等时机预先计算或加载,避免渲染时因CPU负载过高出现帧率波动或卡顿现象。

3.3 限帧法

限帧法简单粗暴,但效果显著,是常见的一种优化手段。限制频率的对象可以是World.Update,物理模拟,粒子计算,角色AI处理,角色状态更新等等。限帧可以通过以下方法实现:

  • 计数法。用一个变量记录更新次数,每累计到某个数才执行更新。
int _frameCounter = 0
void Update(float time)
{
    _frameCounter += 1;
  // 更新频率降为每10帧一次。
  if (_frameCounter % 10 == 0) 
  {
    DoUpdate();      // 执行真正的更新
    _frameCounter = 0;  // 重置计数器
  }
}
  • 计时器。利用Timer机制触发,每隔固定时间触发一次更新。
  • 协程。协程是运行于主线程的伪线程,但可以模拟异步操作,没有多线程的副作用。故而也可以用于限帧操作。
  • 事件触发。每帧查询状态改成事件触发,也是游戏常用的一种优化手段,用来限帧也非常有效。

3.4 主次法

主次法跟LOD技法有异曲同工之妙。思路也是将物件按重要程度划分为高中低级别,然后不同级别采用不同复杂度的效果或计算。这种思路在游戏中可以广泛应用,基本所有消耗高的逻辑或模块都可以采用这个技法。例如:

  • 画质等级。将游戏分为若干等级,画质最高到最低采用不同的渲染技术或资源,区别对待。
  • 资源等级。场景/特效/灯光/物理效果/导航等等模块都可以根据画质等级或物件等级对应不同级别的资源,整体上可以减少消耗,又能兼顾画质效果。
  • 角色分级。主角英雄/Boss等和小怪物/NPC区分开来,前者更新频率更高,AI行为更复杂更智能,而后者采用简单效果或降频更新。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值