1

我有大量数据块(~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 数组吗?

4

1 回答 1

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 函数一起使用,就像任何其他迭代器一样。

于 2015-05-16T19:58:08.743 回答