这是一个"难"的问题.我在网上找不到任何有趣的东西.
我正在为我的公司开发一个内存管理模块.我们为下一代游戏机开发游戏(Xbox 360,PS3和PC ......我们认为PC是控制台!).
我们将来需要为我们的下一个游戏处理大型游戏世界的纹理流,这些游戏世界无法在主控制台内存中加载(暂时不谈论PC).
我们将在纹理的开始高分辨率mipmap(即大约世界数据大小的70%)上进行流式处理.也许在未来我们还必须流式传输几何图形,更小的mipmap,音频等.
我正在为这个问题开发一个内存管理器,专注于X360(因为在PS3上我们可以使用主机内存和相关的自动碎片整理GMM分配器).
我面临的问题如下:我们已决定为纹理流保留一个特定的内存区域(例如64兆字节),我们希望处理该区域中的所有分配和解除分配.我们在应用程序开始时分配了区域,并且该区域在物理上保证是连续的(不仅仅是虚拟,因为我们需要在那里存储纹理).
我已经实现了一个自动碎片整理分配器,使用句柄而不是指针.时间不是问题,问题是内存碎片化.在游戏中我们不断加载和卸载流媒体目标,因此我们希望使用最大量的缓冲区(64兆字节).
使用这个分配器,我们可以使用所有分配的空间,但碎片整理程序在不可接受的时间内工作(有时是60毫秒,超过一帧!),而算法也不算太糟糕......有太多不可避免的memcpy!
我正在寻找解决这个问题的解决方案.我想找到一份好文章,或验尸报告,或者遇到同样问题的人.
现在我在两种策略之间进行选择:1)在专用线程上移动碎片整理例程(适用于具有6个线程的线程的X360,对于PS3而言只有一个新线程...而且不要告诉我使用SPU!)解决锁定区域的所有多线程问题,访问正在移动的区域的问题,... 2)找到碎片整理问题的"增量"解决方案:我们可以为每个帧提供时间预算(例如最多1毫秒)进行碎片整理并且内存管理器将在每帧预算中执行它所能做的事情.
有人可以告诉我他的经历吗?
我最近做了很多关于内存管理的研究,这是我在网上发现的最有用和最有帮助的文章.
http://www.ibm.com/developerworks/linux/library/l-memory/
基于该论文,您将获得的最佳和最快的结果是将64 MB划分为相同大小的块.块的大小取决于您的对象大小.并一次分配或取消分配一个完整的块.它的
比增量垃圾收集更快.
简单.
并且解决了"过多的碎片化"问题.
阅读它,您将找到有关每种可能解决方案的优秀信息,以及每种解决方案的优点和缺点.
为什么不通过纹理大小为流纹理和池使用多个内存区域?
Insomniac有一篇关于PS3纹理流实现的论文.我想它可能会有所帮助:链接.
对于最小化碎片的一般分配策略,Doug Lea可以提供帮助.
但是从我对你的问题的解读来看,这听起来像是在推翻它,我强烈推荐一种混合的方法.(在写入组合内存上运行碎片整理传递听起来也不是特别安全或有趣.)