如何读/写矢量<块*>作为内存映射文件?

How to read/write vector<Chunk*> as memory mapped file(s)?

本文关键字:gt 内存 映射 文件 何读 lt      更新时间:2023-10-16

我有一大组数据块(~50GB)。在我的代码中,我必须能够执行以下操作:

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

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

到目前为止,我已经将数据拆分为 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*>存储在映射的内存中,然后存储块本身。而且,vector<Chunk*>实际上会变成offset_ptr<Chunk>*,即offset_ptr数组?

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

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

#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 函数一起使用。