如何将 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<Chunk*>
。我希望能够非常非常快速地读取这样的文件。
如何读/写这样的vector<Chunk*>
数据结构?我看过boost::interprocess::file_mapping
,但我不知道该怎么做。
我读过这篇文章 (http://boost.cowic.de/rc/pdf/interprocess.pdf),但它并没有说明内存映射文件。我想我会先将vector<Chunk*>
存储在映射内存中,然后再存储块本身。而且,vector<Chunk*>
实际上会变成offset_ptr<Chunk>*
,即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