引擎的资源管理线程化

    五一假期无所事事,唯一值得欣慰的是作出了一个重要决定:将引擎的资源管理线程化。今天写了一个基于 Ring buffer 的双线程同步器,和在此基础上的资源处理器。写好后准备进行资源管理的改造,但是遇上的第一个难题就是如何处理资源加载的异步IO,其实这个问题在上一次的设计中也有提到,当时的方案时没有异步IO,因为将来引擎线程化时,资源的IO处理都是在主逻辑线程,所以对Rendering线程来说,也算是异步IO了,不过今天我推翻了之前的想法,觉得还是应该要异步处理,毕竟游戏逻辑也是不容阻塞的。但问题关键不在如何异步IO,因为线程同步器已经写好,而且引擎的抽象文件系统和线程模型无关,所以这不是问题,问题在于如何处理异步IO对引擎使用者的影响。比如:创建一个角色动画对象,游戏使用诸如 CreateActorFromFile 之类的函数,如果在创建时指定异步IO,很有可能出现对象没有创建好就被使用的情况,比如调用创建函数之后立即设置一个角色动画等。在这种情况下不作处理一定会产生问题。这个问题我之前也想了很久,一直没有想出很好的解决方法。其实我希望能做到外部创建资源而不知道资源加载的视线细节,和同步创建出来的资源相同的使用方式而不需要做任何特殊的处理。但实际上这是不可能做到的,像上面的例子就无法解决。下班后,我在咒骂公交公司害我等了1个小时公交车的过程中的想出了如下的解决方案:为引擎的资源对象增加一个AsyncWaitForLoading函数,无论是否是异步IO创建资源,都可以调用这个函数,如果是异步创建,这个函数内部用傻重试的机制来不断的测试资源是否加载完成,如果是同步创建,则立即返回。这样,当此函数返回时,资源对象就一定可以正常使用。这个在本质上此方案也是让外部知道了引擎资源加载的一些实现细节,不过仅是个函数调用而已,在接口使用上也不会太脏,最主要的是解决了异步加载和对象使用的复杂问题,总体来说是利大于弊。另外从实际的游戏开发中来看,一般静态的关卡资源可以使用异步机制,比如地形、室内、静态物体等,动态对象大多数是同步机制,比如角色(也有例外,比如《苍天》,进入后主城你户会看到走来走去的身体零件,虽然异步,但玩家感觉不好,比较好的是 wow,淡入淡出),即便是异步机制,对于游戏来说也可以是作为预加载技术来使用。此外,还需增加一个查询 Loading 是否完成的函数,为外部提供方便的查询机制。

    接下来就要细分资源的加载过程,我将资源的加载大体上分为4个阶段:磁盘IO读取〉内存对象构建〉设备资源创建〉显存数据填充。这4个阶段是按照时间顺序执行的,理想的情况下每个阶段都是在不同的线程中被处理。磁盘IO读取可以是几个IO线程并行,设备资源的创建一定在渲染线程中,显存数据的填充可以另作一个线程,当然也可以直接放在渲染线程中。我希望各个阶段可以灵活配置,而不受于线程的限制。前面所说的资源创建完成的标志在第2个阶段设置完成时设置。这里有个细节问题还需要说明:引擎的资源之间存在着引用关系,所以当加载一个资源时,在构建其内存对象的过程中会解析出所引用的其他资源,比如角色资源中引用了骨骼资源,骨骼资源中又引用了动画资源等等,这种情况将出现在第2阶段中,由于我希望所有的IO处理都交给IO线程来完成,并且线程同步是基于Ring Buffer机制,所以当需要读取其他资源时,由内存对象构建线程向创建资源的线程投递IO请求,然后再创建资源线程投递IO读取请求,如此反复。

    线程化是个比较复杂的工作,调试起来也比较麻烦,但这是引擎线程化的第一步,没有资源管理的线程化,引擎线程化就是空谈。粗略估算了一下工作量,这要耗掉我80%的时间,不过我已经有近3个月没有对引擎做大的改进了,希望能在5月份完成这个工作。

Advertisements
此条目发表在DreamEngine 3D 图形引擎开发分类目录。将固定链接加入收藏夹。

One Response to 引擎的资源管理线程化

  1. 说道:

    关注中~
    我打算在地形系统中也加入这种异步资源调度方法
    不过我是先准备对ogre的地形管理器做一些修改,然后再回来看这个问题。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google+ photo

You are commenting using your Google+ account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s