如何提高 HDF5 I/O(写入文件)效率?

Posted

技术标签:

【中文标题】如何提高 HDF5 I/O(写入文件)效率?【英文标题】:How to improve HDF5 I/O(write file) efficiency? 【发布时间】:2013-08-14 17:15:14 【问题描述】:

我有很多与时间相关的科学数据要写,这意味着数据应该每隔几秒写入一次 hdf5 文件。我的hdf5文件结构设计如下:

    创建多个时间组,例如 time-1-group、time-2-group、time-3-group 等... 在时间组中,创建了许多数据集,如DataSetA、DataSetB、DataSetC等...... 将数据写入上述数据集。

使用的 API:HDF5-Fortran

运行这个程序,一切正常,但是速度慢,如何提高hdf5写动作效率?非常感谢。

【问题讨论】:

速度慢? 1B/s 慢还是 10GB/s 慢?您获得的文件系统最大写入速率的百分比是多少?你有并行文件系统吗?您的代码是否以任何方式并行化?在调用 HDF5 写入例程之前,您的程序以写入缓冲的方式做什么?这么多问题,这么少的数据...... @HighPerformanceMark 嗨,我不使用并行 API,只使用 h5ltmake_dataset_int() API。大部分科学数据都是二维实数据数组。 我倾向于同意@HighPerformanceMark - I/O 总是很慢。这个输出比什么慢?与仅将数组写入未格式化的 fortran 二进制文件相比,HDF5 输出要慢多少? (不作为推荐的文件 I/O 策略,仅作为简单的基准测试) 【参考方案1】:

您似乎在为每个时间步将数据分成几组(我只是从您写的内容中猜测)。向所有数据集添加一个表示时间步长的额外维度并摆脱组可能更有效,因为您可以在每次写入之前将一堆迭代缓冲在一起。

明确,而不是:

/time-1-group
    /time-1-group/DataSetA -> 2d array
    /time-1-group/DataSetB -> 2d array
    ...
/time-2-group
    /time-2-group/DataSetA -> 2d array
    /time-2-group/DataSetB -> 2d array
    ...
...

你会得到这个:

/DataSetA -> 3d array where third index is time
/DataSetB -> 3d array where third index is time
...

您必须使用分块数据集并小心选择块大小以优化 I/O 效率(正如我上面所说,每个块可以有多个时间步长)。

【讨论】:

嗨,西蒙。非常感谢您的提示和非常清晰的插图。但是我对“摆脱这些组,因为您可以在每次写入之前将一堆迭代缓冲在一起”感到困惑,你能给我举个例子吗?谢谢! 当我说“很清楚,……”时,我举了一个例子。现在,您似乎在根组 (/) 中有组 (time-1-group, time-2-group...),在每个组中都有数据集 (DataSetA, DataSetB...)。我建议您直接在根组中编写数据集,并为每个索引为时间步的数据集添加一个维度。 要了解 bufferchunk 部分,您应该了解 hdf5 的工作原理,而不仅仅是高级接口。您还需要使用 hyperslabs。 HDF5 documentation 很棒。 好的,非常感谢你,simon!~ @Simon - “HDF5 文档很棒” - 你的评论可能是这句话第一次出现anywhere on the internet。

以上是关于如何提高 HDF5 I/O(写入文件)效率?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中将 stl::string 写入 HDF5 文件

如何将自定义类型的列表/数组写入 HDF5 文件?

如何将 Pandas 数据框写入 HDF5 数据集

如何使用 C++ API 在 HDF5 文件中写入/读取锯齿状数组?

如何在 C 中将动态分配的 3D 数组写入 hdf5 文件?

如何高效地向Redis写入大量的数据