如何将 vector<Chunk*> 读/写为内存映射文件?

Posted

技术标签:

【中文标题】如何将 vector<Chunk*> 读/写为内存映射文件?【英文标题】:How to read/write vector<Chunk*> as memory mapped file(s)? 【发布时间】:2013-10-23 01:33:08 【问题描述】:

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

    反复迭代所有块并对它们进行一些计算。

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

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

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

我可以使用内存映射文件代替boost::serialization 吗?

特别是,我会在每个文件中都有一个vector&lt;Chunk*&gt;。我希望能够非常非常快速地读取这样的文件。

如何读/写这样的vector&lt;Chunk*&gt; 数据结构?我看过boost::interprocess::file_mapping,但我不知道该怎么做。

我读过这篇文章 (http://boost.cowic.de/rc/pdf/interprocess.pdf),但它并没有说明内存映射文件。我想我会先将vector&lt;Chunk*&gt; 存储在映射内存中,然后再存储块本身。而且,vector&lt;Chunk*&gt; 实际上会变成offset_ptr&lt;Chunk&gt;*,即offset_ptr 数组?

【问题讨论】:

128 GB RAM 的成本约为 1000 美元。除此之外,这台机器有多少 RAM? 在处理下一个 5 GB 块之前花费了多少时间?我要求确定这是磁盘 IO 问题还是 CPU 问题。快速计算表明,平均磁盘可以在 1220 秒内移动 5 GB(假设 64KB 传输和每次传输 0.015 秒)。 文件是一个字节数组,这就是你在内存映射时得到的。 【参考方案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 函数一起使用,就像任何其他迭代器一样。

【讨论】:

以上是关于如何将 vector<Chunk*> 读/写为内存映射文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将文件读取为vector<vector<double>>?

如何将 std::vector<std::vector<double>> 转换为 torch::Tensor?

如何使用循环将向量推入 queue<vector<int>>?

如何将 std::vector<thrust::device_vector<int>> 转换为 int**?

c++ 在 for 循环中的 vector<char> 中的 for 循环中的内存分配

如何将 std::vector<std::vector<double>> 转换为 Rcpp::Dataframe 或 Rcpp::NumericMatrix