我有一大组数据块(~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*>
存储在映射的内存中,然后再存储Chunks。并且,vector<Chunk*>
实际上会变成offset_ptr<Chunk>*
,即offset_ptr数组?
答案 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函数一起用作任何其他迭代器。