将切片写入使用 h5py 的现有 hdf5 数据非常慢



我有一个(22500,516,516(,uint16 h5py数据集,我想在处理数据后逐个替换。

为此,我通过以下方式加载了多个数据块(块形状为 (1,129,129((:

chunk = data[:,
i1*129:(i1+1)*129,
i2*129:(i2+1)*129].astype(pl.float32)

其中data是数据集和i1, i2索引,它们都在新闻循环中从 0 运行到 3。

在循环的后面,我写入处理后的数据:

data[:,
i1*129:(i1+1)*129,
i2*129:(i2+1)*129] = chunk.astype(pl.uint16)

在这里,我经历了很长的延迟,进程将变得不可中断(状态 D(并导致 0% 的 CPU 负载。内存使用率约为 1%。 更重要的是,与此PC或安装了相同驱动器的服务器的不同ssh会话几乎没有响应。它似乎冻结了一段时间。

但是,如果我在循环之前创建一个新数据集

datanew = entry.create_dataset("data_new",
shape=data.shape,
chunks=data.chunks,
dtype=data.dtype,
compression="gzip",
compression_opts=4)

并改为写入此数据集,我没有遇到任何问题,性能非常好。

新数据集的唯一区别是原始数据集使用lzf压缩。

有什么办法可以理解这里出了什么问题吗?

谢谢

您的 HDF5 文件在哪个存储设备(本地 SSD/硬盘或 NAS(上?

也许由于文件碎片而遇到问题。块是按顺序正常读取和写入的。

如果使用更大的压缩块覆盖压缩区块(使用压缩数据集时可能会发生这种情况(,则区块最终可能会在磁盘上碎片化。性能影响将取决于存储设备(NAS>>本地硬盘驱动器>> SSD(的延迟。

如果您看到这种效果,我会推荐以下方法:

  • 将结果写入临时文件
  • 删除原始数据集(请注意,此处的文件大小不会减小(https://stackoverflow.com/a/33224934/4045774
  • 将数据集从临时文件复制到主 h5 文件 https://stackoverflow.com/a/30610511/4045774
  • 删除临时文件

您可能还希望增加区块大小,以便在访问具有高延迟的存储设备上的文件时获得更好的性能。如果仅以上面显示的方式访问数据集,则可以将块大小增加到 (50,129,129( 甚至更多。 关于不同存储设备上的块大小的一些简单工作台: https://stackoverflow.com/a/44961222/4045774

最新更新