这是一个“难”的问题。我在网上没有发现任何有趣的东西。
我正在为我的公司开发一个内存管理模块。我们为下一代游戏机(Xbox 360、PS3 和 PC……我们将 PC 视为游戏机!)开发游戏。
未来,对于我们的下一款游戏,我们需要处理无法全部加载到主机内存中的大型游戏世界的纹理流传输(暂时不讨论 PC)。
我们将在开始时流式传输纹理的高分辨率 mipmap(大约是世界数据大小的 70%)。也许将来我们还必须流式传输几何、较小的 mipmap、音频等。
我正在为这个问题开发一个内存管理器,专注于 X360(因为在 PS3 上我们可以使用主机内存和相关的自动碎片整理 GMM 分配器)。
我面临的问题如下:我们决定为纹理流式传输保留一个特定的内存区域(例如 64 兆字节),并且我们希望处理该区域中的所有分配和解除分配。我们在应用程序开始时分配了该区域,并且该区域在物理上保证是连续的(不仅仅是虚拟的,因为我们需要在那里存储纹理)。
我实现了一个自动碎片整理分配器,使用句柄而不是指针。时间不是问题,问题是内存碎片。在游戏中,我们不断地加载和卸载流目标,因此我们希望使用我们的缓冲区的最大数量(64 兆字节)。
有了这个分配器,我们可以使用所有分配的空间,但是碎片整理程序在一个不可接受的时间内工作(有时 60 毫秒,超过一帧!)而算法还不错......有太多不可避免的 memcpy!
我正在寻找解决此问题的解决方案。我想至少找到一篇好论文,或验尸报告,或遇到与我相同问题的人。
现在我在两种策略之间进行选择:1)在专用线程上移动碎片整理例程(对于具有 6 个硬件线程的 X360 来说很好,对于只有一个硬件线程的 PS3 来说很糟糕......而且不要告诉我使用 SPU!)锁定区域的所有多线程问题,访问正在移动的区域,... 2)找到碎片整理问题的“增量”解决方案:我们可以给每个帧一个时间预算(例如最多 1 毫秒)进行碎片整理并且内存管理器将在每一帧的预算中做它可以做的事情。
有人能告诉我他的经历吗?