优化HDF5数据集的读/写速度

时间:2017-04-21 04:22:01

标签: python h5py large-data

我目前正在进行一项实验,即在空间扫描目标并在每个离散像素处抓取示波器轨迹。通常我的跟踪长度是200Kpts。在扫描整个目标之后,我在空间上组装这些时域信号,并基本上回放被扫描内容的电影。我的扫描区域大小为330x220像素,因此整个数据集大于我必须使用的计算机上的RAM。

首先,我只是将每个示波器轨迹保存为numpy数组,然后在我的扫描完成下采样/过滤等之后,然后以不会遇到内存问题的方式将电影拼接在一起。但是,我现在处于不能下采样的地方,因为会出现混叠,因此需要访问原始数据。

我开始考虑使用H5py将我的大型3D数据块存储在HDF5数据集中。我的主要问题是我的块大小分配。我的传入数据与我想读出来的平面正交。我编写数据的主要选项(据我所知)是:

    #Fast write Slow read
    with h5py.File("test_h5py.hdf5","a") as f:
        dset = f.create_dataset("uncompchunk",(height,width,dataLen),chunks = (1,1,dataLen), dtype = 'f')
        for i in range(height):
            for j in range(width):
                dset[i,j,:] = np.random.random(200000)

    #Slow write Fast read
    with h5py.File("test_h5py.hdf5","a") as f:
        dset = f.create_dataset("uncompchunk",(height,width,dataLen),chunks = (height,width,1), dtype = 'f')
        for i in range(height):
            for j in range(width):
                dset[i,j,:] = np.random.random(200000)     

我是否有某种方法可以优化这两种情况,以便运行效率都不高?

2 个答案:

答案 0 :(得分:1)

如果你想通过分块来优化你的I / O性能,你应该从unidata阅读这两篇文章:

chunking general

optimising for access pattern

如果您只是考虑原始I / O性能,请考虑@titusjan建议

答案 1 :(得分:0)

您的代码中存在一些性能缺陷。

  1. 您正在使用某种花式索引(在读取/写入HDF5数据集时不要更改数组调度的数量。
  2. 如果您没有读取或写入整个块,请设置正确的块高速缓存大小。 https://stackoverflow.com/a/42966070/4045774

  3. 减少对HDF5-Api的读写调用量。

  4. 选择适当的块大小(块只能完全读/写,所以如果你只需要一块的一部分,其余部分应保留在缓存中)
  5. 以下示例使用HDF5-API进行缓存。要设置适当的缓存大小,我将使用h5py_cache。 https://pypi.python.org/pypi/h5py-cache/1.0.1

    如果您自己进行缓存,则可以进一步提高性能。 (读写整个块)

    <强>编写

    # minimal chache size for reasonable performance would be 20*20*dataLen*4= 320 MB, lets take a bit more
    with h5py_cache.File(h5pyfile, 'r+',chunk_cache_mem_size=500*1024**2) as f:
        dset = f.create_dataset("uncompchunk",(height,width,dataLen),chunks = (20,20,20), dtype = 'f')
        for i in range(height):
            for j in range(width):
                # avoid fancy slicing
                dset[i:i+1,j:j+1,:] = expand_dims(expand_dims(np.random.random(200000),axis=0),axis=0)
    

    <强>读

    # minimal chache size for reasonable performance would be height*width*500*4= 145 MB, lets take a bit more
    with h5py_cache.File(h5pyfile, 'r+',chunk_cache_mem_size=200*1024**2) as f:
         dset=f["uncompchunk"]
         for i in xrange(0,dataLen):
             Image=np.squeeze(dset[:,:,i:i+1])