如何读取/写入vector <chunk *>作为内存映射文件?</chunk *>

时间:2013-10-23 01:33:09

标签: c++ memory boost boost-interprocess

我有一大组数据块(~50GB)。在我的代码中,我必须能够做以下事情:

  1. 反复遍历所有块并对它们进行一些计算。

  2. 重复遍历所有块并对它们进行一些计算,在每次迭代中,访问块的顺序(尽可能)随机化。

  3. 到目前为止,我已将数据拆分为10个二进制文件(使用boost::serialization创建)并反复逐个读取并执行计算。对于(2),我以随机顺序读取10个文件并按顺序处理每个文件,这已经足够了。

    然而,阅读其中一个文件(使用boost::serialization)需要很长时间,我想加快速度。

    我可以使用内存映射文件而不是boost::serialization吗?

    特别是,我在每个文件中都有一个vector<Chunk*>。我希望能够非常快速地阅读这样一个文件。

    如何读/写这样的vector<Chunk*>数据结构?我查看了boost::interprocess::file_mapping,但我不知道该怎么做。

    我读过这篇文章(http://boost.cowic.de/rc/pdf/interprocess.pdf),但对内存映射文件并没有多说。我想我会先将vector<Chunk*>存储在映射的内存中,然后再存储Chunks。并且,vector<Chunk*>实际上会变成offset_ptr<Chunk>*,即offset_ptr数组?

1 个答案:

答案 0 :(得分:1)

内存映射文件是一块内存,与任何其他内存一样,它可以按字节,小端字,位或任何其他数据结构组织。如果可移植性是一个问题(例如字节顺序),则需要注意。

以下代码可能是一个很好的起点:

#include <cstdint>
#include <memory>
#include <vector>
#include <iostream>
#include <boost/iostreams/device/mapped_file.hpp>

struct entry {
  std::uint32_t a;
  std::uint64_t b;
} __attribute__((packed)); /* compiler specific, but supported 
                              in other ways by all major compilers */

static_assert(sizeof(entry) == 12, "entry: Struct size mismatch");
static_assert(offsetof(entry, a) == 0, "entry: Invalid offset for a");
static_assert(offsetof(entry, b) == 4, "entry: Invalid offset for b");

int main(void) {
  boost::iostreams::mapped_file_source mmap("map");
  assert(mmap.is_open());
  const entry* data_begin = reinterpret_cast<const entry*>(mmap.data());
  const entry* data_end = data_begin + mmap.size()/sizeof(entry);
  for(const entry* ii=data_begin; ii!=data_end; ++ii)
    std::cout << std::hex << ii->a << " " << ii->b << std::endl;
  return 0;
}

data_begin和data_end指针可以与大多数STL函数一起用作任何其他迭代器。