我在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透明完成的。
答案 0 :(得分:1)
h5py
通过过滤器处理LZF文件的解压缩。过滤器的源代码(用C语言实现)为available on the h5py Github here。查看implementation of lzf_decompress
,它是导致瓶颈的函数,您会发现它不是并行的(不知道它是否可以并行,我将把判断权留给对LZF内部工作更熟悉的人)。
话虽如此,我恐怕没有办法只是将巨大的压缩文件进行多线程解压缩。据我所知,您的选择是:
multiprocessing
可能会有所帮助,但您需要注意进程间共享内存)并加入所有内容解压缩后返回到一起。