如何加快从压缩的HDF5文件读取的速度

时间:2019-03-22 09:53:48

标签: python python-3.x hdf5 h5py

我在SSD上存储了几个大的HDF5文件(lzf压缩文件大小为10–15 GB,未压缩大小为20–25 GB)。将此类文件中的内容读取到RAM中以进行进一步处理,每个文件大约需要2分钟。在此期间,仅使用了一个内核(但利用率为100%)。因此,我猜想CPU上运行的减压部分是瓶颈,而不是SSD的IO吞吐量。

在我的程序开始时,它将多个此类文件读取到RAM中,这需要花费一些时间。 我想通过利用更多的内核以及最终更多的RAM来加快该过程,直到SSD IO吞吐量成为限制因素。我正在使用的计算机具有足够的资源(20个CPU内核[+ 20 HT]和400 GB RAM),并且只要浪费时间证明“浪费” RAM没什么大不了的。

我自己有两个想法:

1)使用python的multiprocessing模块将多个文件并行读入RAM。这原则上可行,但是由于在multiprocessing(如here中使用了Pickle,我达到了4 GB的序列化限制:

  

OverflowError('无法序列化大于4 GiB的字节对象')。

2)使多个进程(使用Pool模块中的multiprocessing)打开同一HDF5文件(使用with h5py.File('foo.h5', 'r') as h_file:),从中读取单个块({{1} },然后返回该块。然后将收集的块连接起来。但是,这失败并显示

  

OSError:无法读取数据(Fletcher32校验和检测到数据错误)。

这是否是由于我在多个进程中打开了相同的文件(如建议的here)?


所以我的最后一个问题是:如何将chunk = h_file['label'][i : i + chunk_size]文件的内容更快地读入主存储器?再次:允许浪费时间的“浪费” RAM。内容必须驻留在主存储器中,因此仅读取行或分数来解决问题就不可行。 我知道我可以只存储未压缩的.h5文件,但这只是我要使用的最后一个选项,因为SSD上的空间不足。我更喜欢压缩文件和快速读取两者(最好是更好地利用可用资源)。

元信息:我使用python 3.5.2和h5py 2.8.0。


编辑:在读取文件时,SSD的工作速度为72 MB / s,而不是其最大值。通过使用h5py的create_dataset方法和.h5选项来创建.h5文件。

编辑2:这是(用来简化)我用来读取(压缩)HDF5文件内容的代码:

compression="lzf"

如您所见,减压是由h5py透明完成的。

1 个答案:

答案 0 :(得分:1)

h5py通过过滤器处理LZF文件的解压缩。过滤器的源代码(用C语言实现)为available on the h5py Github here。查看implementation of lzf_decompress,它是导致瓶颈的函数,您会发现它不是并行的(不知道它是否可以并行,我将把判断权留给对LZF内部工作更熟悉的人)。

话虽如此,我恐怕没有办法只是将巨大的压缩文件进行多线程解压缩。据我所知,您的选择是:

  • 将大文件拆分为较小的单独压缩的块,将每个块并行解压缩到一个单独的内核上(multiprocessing可能会有所帮助,但您需要注意进程间共享内存)并加入所有内容解压缩后返回到一起。
  • 只使用未压缩的文件。