上一篇我们讲到了AI架构之一的行为树,本篇文章和下一篇文章我们将对行为树进行优化,在本篇文章中我们讲到的是内存优化

问题##

上一篇中我们设计的行为树由于直接采用new进行动态内存分配,没有自己进行管理。因此行为树各节点的存储位置会散布在内存空间的各处,行为树在不同节点中切换时会导致Cache频繁失效。

通过内存管理改变行为树节点的内存分布,可以显著提高行为树的内存性能。

解决办法##

我们可以在BehaviorTree中引入一组内存分配的API来保证各节点尽量分配在连续的内存上,代码如下

BehaviorTree(Behavior*InRoot):Root(InRoot),
Buffer(new uint8_t[MaxBehaviorTreeMemory]),Offset(0){}
~BehaviorTree(){ delete[] Buffer; } template<typename T>
T* Allocate()
{
T* Node = new((void*)((uintptr_t)Buffer + Offset)) T;
Offset += sizeof(T);
assert(Offset < MaxBehaviorTreeMemory);
return Node;
}

我们在BehaviorTree中引入一个Allocate函数用来负责所有节点的内存分配。

当行为树被构造时,一块用于保存节点的内存空间Bufffer会随之分配,Allocate函数通过Placement new在Buffer上进行内存分配,通过Offset记录分配已分配内存的偏移地址。

通过这种方式我们可以让节点分配在连续的内存上,同时通过控制分配节点的顺序(如深度遍历广度遍历等),我们可以进一步减少行为树遍历时产生的Cache失效,提高内存性能。)

复合节点

除了对节点分配进行优化,我们还可以改变复合节点的内存布局,进一步提升性能。

class Composite :public Behavior
{
public:
friend class BehaviorTree;
virtual void AddChild(Behavior* InChild) override
{
assert(ChildrenCount < MaxChildrenPerComposite);
ptrdiff_t p = (uintptr_t)InChild - (uintptr_t)this;
assert(p < std::numeric_limits<uint16_t>::max());
Children[ChildrenCount++] = static_cast<uint16_t>(p);
} Behavior* GetChild(size_t index)
{
assert(index < MaxChildrenPerComposite);
return (Behavior*)((uintptr_t)this + Children[index]);
} size_t GetChildrenCount()
{
return ChildrenCount;
} protected:
uint16_t Children[MaxChildrenPerComposite];
uint16_t ChildrenCount = 0;
};

在如上代码中,我们通过静态数组代替vector,避免在存储时vector所产生的额外堆操作,通过用保存子节点相对于复合节点的偏移地址来代替直接保存子节点指针以节省内存空间。由于更换了子节点的存储方式,我们需要通过getchild()函数来根据复合节点地址和子节点偏移地址获得子节点指针。

总结

以上,就是关于行为树的内存优化方式,当然凡事无绝对,究竟如何构造行为树应当根据实际情况选择,下一篇我们将讲述另一种行为树优化方法。

[gihub链接][1]

游戏AI(二)—行为树优化之的更多相关文章

  1. 游戏AI(三)—行为树优化之基于事件的行为树

    上一篇我们讲到了关于行为树的内存优化,这一篇我们将讲述行为树的另一种优化方法--基于事件的行为树. 问题 在之前的行为树中,我们每帧都要从根节点开始遍历行为树,而目的仅仅是为了得到最近激活的节点,既然 ...

  2. 游戏AI:行为树

    Behavior Tree 行为树通过子Task的返回值决定整棵树的走向 Task 行为树上的每个节点都称为一个Task, 每个Task存在三种状态, success, failure, runnin ...

  3. 使用行为树(Behavior Tree)实现游戏AI

    ——————————————————————— 谈到游戏AI,很明显智能体拥有的知识条目越多,便显得更智能,但维护庞大数量的知识条目是个噩梦:使用有限状态机(FSM),分层有限状态机(HFSM),决策 ...

  4. 游戏AI之决策结构—有限状态机/行为树(2)

    目录 有限状态机 行为树 控制节点 条件节点 行为节点 装饰节点 总结 额外/细节/优化 游戏AI的决策部分是比较重要的部分,游戏程序的老前辈们留下了两种经过考验的用于AI决策的结构: 有限状态机 行 ...

  5. 做游戏长知识------基于行为树与状态机的游戏AI(一)

    孙广东 2014.6.30 AI. 我们的第一印象可能是机器人,如今主要说在游戏中的应用. 现代的计算机游戏中已经大量融入了AI元素,平时我们进行游戏时产生的交互都是由AI来完毕的.比方在RPG游戏中 ...

  6. Unity教程之-基于行为树与状态机的游戏AI

    AI.我们的第一印象可能是机器人,现在主要说在游戏中的应用.关于AI的相关文章我们在前面也提到过,详细请戳这现代的计算机游戏中已经大量融入了AI元素,平时我们进行游戏时产生的交互都是由AI来完成的.比 ...

  7. BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】

    Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...

  8. HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle  Accepts: 42  Submissions: 26 ...

  9. BZOJ 3594: [Scoi2014]方伯伯的玉米田 (二维树状数组优化DP)

    分析 首先每次增加的区间一定是[i,n][i,n][i,n]的形式.因为如果选择[i,j](j<n)[i,j](j<n)[i,j](j<n)肯定不如把后面的全部一起加111更优. 那 ...

随机推荐

  1. 建立LINUX服务器

    建立LINUX服务器:一. 下载UltraISO工具并用该工具制作LINUX启动U盘,制作步骤如下:http://www.linuxidc.com/Linux/2012-11/74695.htm [^ ...

  2. Deploy .Net project automatically with MsBuild and MsDeploy (0)

    I will use a example of my project to show how to use MS Build and MS Deploy in a real project and s ...

  3. 基于HTML5的WebGL经典3D虚拟机房漫游动画

    第一人称在 3D 中的用法要参考第一人称在射击游戏中的使用,第一人称射击游戏(FPS)是以第一人称视角为中心围绕枪和其他武器为基础的视频游戏类型 ; 也就是说,玩家通过主角的眼睛来体验动作.自从流派开 ...

  4. padding-使用必记

    前言 说起了padding可谓是盒子模型中最常用的一个属性,你真的了解padding吗?那我请问您设置padding会影响盒子的宽度与高度吗?也许好多人会回答padding会影响到盒子的宽度与高度.在 ...

  5. [转载] zookeeper 分布式锁服务

    转载自http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...

  6. 前端如何处理emoji表情

    这段时间在做移动端的开发, 有一个功能就是发表评论,其实这个功能本身是比较简单的, 但是在提测是的时候QA给哦提了一个bug,说输入手机自带的emoji表情发送失败了.我就奇怪了,emoji表情也是文 ...

  7. 一步一步搞懂支持向量机——从牧场物语到SVM(上)

    之前在数据挖掘课程上写了篇关于SVM的"科普文",尽量通俗地介绍了SVM的原理和对各公式的理解.最近给正在初学机器学习的小白室友看了一遍,他觉得"很好,看得很舒服&quo ...

  8. input[type='file']样式美化及实现图片预览

    前言 上传图片是常见的需求,多使用input标签.本文主要介绍 input标签的样式美化 和 实现图片预览. 用到的知识点有: 1.input标签的使用 2.filelist对象 和 file对象 3 ...

  9. [DFS遍历图]UVA10562 Undraw the Trees

    传送门: 1. UVA - 10562 2. Vjudge [看图写树]     将题目中给出的树改写为 括号表示法 即 (ROOT (SON1(...) (SON2(...)...(SONn(... ...

  10. 字节、十六进制字符串相互转换(asc2hex、hex2asc)

    //================================================================== /** 功能: 将16进制数组转换成asc字符数组(短转长) ...