【问题标题】:Random-access container that does not fit in memory?不适合内存的随机访问容器?
【发布时间】:2010-01-25 19:30:31
【问题描述】:

我有一个对象数组(例如图像),它太大而无法放入内存(例如 40GB)。但是我的代码需要能够在运行时随机访问这些对象。

最好的方法是什么?

从我的代码的角度来看,当然,某些数据是在磁盘上还是临时存储在内存中并不重要;它应该具有透明的访问权限:

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

但是我应该如何实现这个容器呢?它应该只是将请求发送到数据库吗?如果是这样,哪一个是最好的选择? (如果是数据库,那么它应该是免费的,并且没有太多的管理麻烦,也许是 Berkeley DB 或 sqlite?)

我应该自己实现它,在访问沙子后记住对象并在内存满时清除内存吗?或者那里有很好的库(C++)吗?

对容器的要求是它最大限度地减少磁盘访问(我的代码可能更频繁地访问某些元素,因此它们应该保存在内存中)并允许快速访问。

更新:我发现 STXXL 不适用于我的问题,因为我存储在容器中的对象具有动态大小,即我的代码可能会更新它们(增加或减少某些对象的大小) 在运行时。但 STXXL 无法处理:

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

您能否对其他解决方案发表评论?使用数据库怎么样?还有哪一个?

【问题讨论】:

  • 在不了解您的问题的情况下,我会说两者(从磁盘读取并缓存一些结果;或使用带有缓存的数据库)都是很好的解决方案
  • 如果你在修改对象,你不是在创建一个新对象吗?然后你要么拥有旧对象和新对象,要么删除旧对象并用新对象替换它。

标签: c++ database memory data-structures random-access


【解决方案1】:

考虑使用STXXL

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

【讨论】:

  • 这看起来不错,但我不知道是否可以告诉它缓存或预加载某些结果?例如,一旦我访问元素 n,我可能很快就会访问从 n-100 到 n+100 的一些元素,因此它应该将它们加载并存储在内存中。在这种情况下,也许我需要自己的定制解决方案?
  • STXXL 对我不起作用,请参阅我的问题中的更新。还有其他想法吗?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        我看到了一些非常聪明的代码,它们重载了operator[]() 以动态执行磁盘访问并透明地从磁盘/数据库加载所需的数据。

        【讨论】:

        • 当然,我在问是否值得自己编写该代码(如果是,最好的方法是什么:数据库访问等?)或者该代码是否可用。
        猜你喜欢
        • 2018-02-23
        • 1970-01-01
        • 2012-06-03
        • 2017-01-08
        • 1970-01-01
        • 2012-09-16
        • 1970-01-01
        • 2015-07-20
        • 2020-02-28
        相关资源
        最近更新 更多