【问题标题】:Optimising HDF5 dataset for Read/Write speed优化 HDF5 数据集的读/写速度
【发布时间】:2017-09-17 22:29:24
【问题描述】:

我目前正在进行一项实验,我在空间上扫描目标并在每个离散像素处获取示波器轨迹。通常我的走线长度是 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)     

有没有什么方法可以优化这两种情况,使它们的运行效率都非常低?

【问题讨论】:

  • 如果您事先知道数据集的大小,并且不想使用压缩,则可以使用连续存储(即无块)。你不能试试吗?

标签: python h5py large-data


【解决方案1】:

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

  1. 您在行中使用了某种花哨的索引(在读取/写入 HDF5 数据集时不要更改数组暗淡的数量。
  2. 如果您不读取或写入整个块,请设置适当的块缓存大小。 https://stackoverflow.com/a/42966070/4045774

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

  4. 选择适当的块大小(块只能完全读取/写入,因此如果您只需要块的一部分,则其余部分应保留在缓存中)

以下示例使用 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])

【讨论】:

    【解决方案2】:

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

    chunking general

    optimising for access pattern

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

    【讨论】:

      猜你喜欢
      • 2012-04-03
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 2013-08-23
      • 1970-01-01
      • 1970-01-01
      • 2012-03-26
      相关资源
      最近更新 更多