这是一个很“难”的问题。我在网上没找到有趣的东西。
我正在为我的公司开发内存管理模块。我们为下一代游戏机(Xbox 360、PS3和PC…我们认为PC是游戏机!)开发游戏。
为了处理无法全部加载到主控制台内存中的大型游戏世界(暂不考虑PC),在未来的游戏中我们需要进行纹理流处理。
我们将在开始时流式传输纹理的高分辨率mipmap(大约占据世界数据大小的70%)。也许在未来我们还需要流式传输几何图形、更小的mipmap、音频等。
我正在为此问题开发一个内存管理器,重点针对X360(因为在PS3上我们可以使用主机内存和相关自动碎片整理GMM分配器)。
我面临的问题是:我们已经决定为纹理流式传输保留一个特定的内存区域(例如64兆字节),并且我们希望在该区域处理所有分配和释放。我们已经在应用程序开始时分配了该区域,并且物理上保证是连续的(不仅仅是虚拟的,因为我们需要在那里存储纹理)。
我实现了一个使用句柄而不是指针的自动碎片整理分配器。时间不是问题,问题是内存碎片。在游戏中,我们不断地加载和卸载流式传输目标,因此我们希望使用我们缓冲区的最大容量(64兆字节)。
通过这个分配器,我们可以使用所有已分配的空间,但碎片整理例程的运行时间过长(有时需要60毫秒,超过了一帧!),尽管算法并不太糟糕…只是有太多不可避免的memcpy!
我正在寻找解决这个问题的方法。我希望至少能找到一篇好的论文、或者一篇事后总结、或者有人曾经面临过和我同样的问题。
现在我正在选择两种策略: 1)将碎片整理例程移动到专用线程上(对于拥有6个硬件线程的X360来说很好,对于只有一个硬件线程的PS3来说很差…别告诉我要使用SPU!)会有所有多线程锁定区域、访问正在移动的区域等多线程问题。2) 找到一种“增量”解决碎片整理问题的方法:我们可以为每个帧分配一个时间预算(例如最多1毫秒)进行碎片整理,内存管理器将在每个帧中尽力完成预算内的任务。
有人能分享他的经验吗?