2010-01-25 51 views
6

我有一个对象数组(例如图像),它太大而不适合内存(例如40GB)。但是我的代码需要能够在运行时随机访问这些对象。不适合内存的随机存取容器?

这样做的最好方法是什么?

从我的代码的角度来看,当然,如果某些数据在磁盘上或临时存储在内存中,这应该没有关系;它应该有透明访问:

container.getObject(1242)->process(); 
container.getObject(479431)->process(); 

但是我应该如何实现这个容器?它应该只是将请求发送到数据库?如果是这样,哪一个将是最好的选择? (如果一个数据库,那么它应该是免费的,没有太多的管理麻烦,可能是伯克利DB或SQLite?)

我应该自己实现它,记忆存取后的对象清理内存时,它已满?或者有没有好的库(C++)?

对容器的要求是最小化磁盘访问(某些元素可能会被我的代码更频繁地访问,所以它们应该保存在内存中)并允许快速访问。

更新:我原来是STXXL不适合我的问题的工作,因为我存储在容器中的对象有动态的大小,也就是我的代码可以更新他们(增加或减少某些物体的大小),在运行时。但是STXXL无法处理:

STXXL容器假定他们存储数据 类型是普通的旧数据 类型(POD)。 http://algo2.iti.kit.edu/dementiev/stxxl/report/node8.html

请问您可以对其他解决方案发表评论吗?怎么样使用数据库?哪一个?

+0

不知道更多关于你的问题,我会说(从磁盘读取和缓存一些结果;或使用数据库缓存)是很好的解决方案 – 2010-01-25 19:33:10

+0

如果你修改对象,是不是你创建一个新的对象?然后,您要么拥有旧对象,要么删除旧对象,并用新对象替换它。 – codeDr 2011-07-15 18:54:48

回答

1

您可以查看内存映射文件,然后访问其中的一个。

8

考虑使用STXXL

STXXL的核心是一个执行的C的 ++标准模板库 STL为外部存储器(外的核心) 计算,即,STXXL实现 容器以及可以处理大量数据的算法,只有 适合磁盘。虽然STL的兼容性 支持易用性和 与现有 应用程序的兼容性,但另一个设计优先级 是高性能。

+0

这看起来不错,但我不知道是否有可能告诉它缓存或预加载某些结果?例如,一旦我访问元素n,我可能很快就会从n-100到n + 100访问一些元素,因此它应该加载并将它们存储在内存中。也许我需要我自己的定制解决方案在这种情况下? – Frank 2010-01-25 20:07:39

+0

STXXL不适用于我,请参阅我的问题中的更新。任何其他想法? – Frank 2010-01-26 15:00:43

1

我会实现一个基本的缓存。有了这个工作集大小,您将获得带有x字节缓存行(x ==与您的访问模式最匹配的集合关联缓存)的最佳结果。只需在软件中实现每个现代处理器在硬件上已具备的功能。这应该给你最好的结果。如果你可以优化访问模式是线性的,你可以进一步优化它。

0

一个解决方案是使用类似于B树,数组或向量的索引和“页”的结构。其概念是索引用于确定将哪个页面加载到内存中以访问您的变量。

如果您使页面尺寸更小,则可以在内存中存储多个页面。基于使用频率或其他规则的缓存系统将减少页面加载次数。

0

我见过一些非常聪明的代码,它们会重载operator[]()来即时执行磁盘访问,并透明地从磁盘/数据库加载所需的数据。

+0

当然,我在问自己是否值得自己写代码(如果是这样,最好的方法是什么:数据库访问等?)或者代码是否可用。 – Frank 2010-01-26 14:53:58