我有一个巨大的 hdf5 文件(~100GB,连续存储),我需要随机访问不同的点。在 python/h5py 或 C/H5Dread 中使用索引似乎很慢,因此我想直接映射数据。
事实上,这可以在我本地 64 位 Fedora 25 上的 h5py/numpy 中运行,遵循 this 。但在远程集群上,numpy/mmap 对于大文件失败([Errno 12] Cannot allocate memory
),即使 python 似乎是 64 位并且在 C 中使用 mmap 对 100GB 文件进行简单测试也是如此。所以我的集群的Python可能有问题。
我看到的一个解决方案是在 C 中使用 mmap。我写了一个小 test创建一个带有 1d 数据集的小型 hdf5 并使用“H5Dget_offset”获取数据集偏移量。但是,结果不正确。
核心代码如下:
/* Get dataset offset within file */
file_id = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
dataset_id = H5Dopen2(file_id, "/dset", H5P_DEFAULT);
offset = H5Dget_offset(dataset_id);
fd = open(FILE, O_RDONLY);
// align with page size
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
length = NX * NY * sizeof(int);
addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
在此下的讨论blog提到了 Julia 中通过 H5Fget_vfd_handle
和 H5Dget_offset
实现这一点的实现,但我还没有找到详细/简单的解释。
- 我通过 python/h5py 的
dataset.id.get_offset
获得的偏移量与我通过 C 中的H5Dget_offset
获得的偏移量相同。 - 我认为我的核心问题是:如何使用 C 的
H5Dget_offset
给出的偏移量来映射数据集。 mmap
应该比简单的 hdf5 访问快得多吗?
最佳答案
您的问题的主要原因与 HDF 库无关。您没有映射 HDF 库告诉您的与数据集相对应的字节。
H5Dget_offset
返回从文件开头到相关数据集开头的偏移量(以字节为单位)。但您没有将该值传递给 mmap(2)
。您正在计算实际偏移量下方的页面大小的倍数,然后使用该作为mmap(2)<中文件的偏移量
调用。
而不是:
mmap(..., pa_offset);
你应该有
mmap(..., offset);
至于这是否会更快。 HDF 库很复杂。可能会有很大的开销(边界检查、权限检查、其他库调用),但也可能得到相当好的优化。确定内存映射是否更快的唯一合理方法是对其进行测量。
关于c - C/C++ 中的 mmap hdf5 数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46636174/