c - C/C++ 中的 mmap hdf5 数据集

标签 c numpy hdf5 mmap

我有一个巨大的 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_handleH5Dget_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/

相关文章:

python - 用 Python 写矩阵,用 Torch 读,哪里出错了

c++ - Matlab转C++代码生成(hdf5格式)

c - Makefile:没有链接问题的编译

Mac OS X El Capitan 可以运行为 Yosemite 编译的需要/usr/gnu64/lib 中的库的软件吗?

c - Unistd read() 最大尺寸

python - 计算每个指数平均值的最快方法

python - 调用 np.array(data) 时给出 MemoryError 的大而稀疏的列表

c++ - 无论如何有一个 valgrind 消息 "Conditional jump or move depends on uninitialized value"可以是所谓的 'false positive'

python - 在 python 或 numpy 中合并记录

java - 如何使用 JHDF5 读取/写入 3D+ 数组?