上一篇我们讲到了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. 三星R428 内存不兼容金士顿2G DDR3

    京东上买了个金士顿2G DDR3, 回家装上之后发现不兼容, 原机带的是三星DDR3 1066的2G条子,买的是 金士顿DDR3 2G 1333的条子,结果单独插任何一根都好使,两个插槽均无问题,但是 ...

  2. Java_数据交换_fastJSON_01_用法入门

    一.用法 1.序列化—将Object转为Json对象 Object data=JSON.toJSON( MyObject ); 注:本文的Object可以是Map.List.javaBean等 需求: ...

  3. MongoDB可视化界面配置

    环境:windows 10 64bit 1. 以管理员身份运行cmd cd E:\MongoDB\Server\3.4\bin 2. 在data文件夹中建立logs目录 3. 在logs目录下建立mo ...

  4. 记录一次Session偶尔获取不到的解决过程

    导读 平台下某子系统有密码登录需求,初步考虑用Session,登录后设置Session[key]=value;Session中若某key对应的Session,即Session[key]为null则限制 ...

  5. [转载] 红黑树(Red Black Tree)- 对于 JDK TreeMap的实现

    转载自http://blog.csdn.net/yangjun2/article/details/6542321 介绍另一种平衡二叉树:红黑树(Red Black Tree),红黑树由Rudolf B ...

  6. [转载] java多线程学习-java.util.concurrent详解(一) Latch/Barrier

    转载自http://janeky.iteye.com/blog/769965     Java1.5提供了一个非常高效实用的多线程包:java.util.concurrent, 提供了大量高级工具,可 ...

  7. ButterKnife的使用以及不能自动生成代码问题的解决

    ButterKnife的使用以及不能自动生成代码问题的解决 转载请注明出处:http://www.cnblogs.com/zhengjunfei/p/5910497.html 最近换了个工作刚入职,又 ...

  8. Mina自定义协议简单实现

    因公司需要做个电子秤自动称重系统,需要自定义协议实现,所以就用Mina简单实现了一下,有时间改成Netty版 服务端 package net.heartma.server;import java.io ...

  9. Android studio导出配置

    在使用 Android Studio 时,往往会进行一些设置,比如 界面风格.字体.字体大小.快捷键.常用模板等.但是这里的设置只能用在一个版本的 Android Studio 上,如果下载了新的 A ...

  10. scrapy初试水 day01

    1.安装pip install Scrapy#一定要以管理员身份运行dos窗口conda install scrapy2.创建项目scrapy startproject hello3.在hello/s ...