当前位置: 首页 > 知识库问答 >
问题:

有没有办法打开带有POSIX_FADV_DONTNEED标志的hdf5文件?

蓝飞
2023-03-14

我们正在为机器学习应用程序使用python中的h5py处理大型(1.2TB)未压缩、未分块的hdf5文件,这需要我们重复处理完整的数据集,以随机顺序单独加载约15MB的切片。我们正在使用具有192 GB RAM的linux(Ubuntu 18.04)机器。我们注意到该程序正在慢慢填充缓存。当缓存的总大小达到与整机RAM相当的大小时(前0位的可用内存几乎为0,但有大量“可用”内存)交换会减慢所有其他应用程序的速度。为了查明问题的根源,我们编写了一个单独的最小示例来隔离我们的数据加载过程——但发现问题独立于我们方法的每个部分。

我们尝试:构建numpy memmap并访问请求的切片:

#on init:
f = h5py.File(tv_path, 'r')
hdf5_event_data = f["event_data"]
self.event_data = np.memmap(tv_path, mode="r", shape=hdf5_event_data.shape,                                           
                            offset=hdf5_event_data.id.get_offset(),dtype=hdf5_event_data.dtype)
self.e = np.ones((512,40,40,19))

#on __getitem__:
self.e = self.event_data[index,:,:,:19]
return self.e

在每次调用getitin时重新打开memmap:

#on __getitem__:
self.event_data = np.memmap(self.path, mode="r", shape=self.shape,
                                            offset=self.offset, dtype=self.dtype)
self.e = self.event_data[index,:,:,:19]
return self.e

直接寻址h5文件并转换为numpy数组:

#on init:
f = h5py.File(tv_path, 'r')
hdf5_event_data = f["event_data"]
self.event_data = hdf5_event_data
self.e = np.ones((512,40,40,19))

#on __getitem__:
self.e = self.event_data[index,:,:,:19]
return self.e

我们还在pytorch数据集/数据加载器框架中尝试了上述方法,但没有什么不同。

我们观察到高内存碎片,如/proc/buddyinfo所示。通过同步删除缓存;回声3

我们的工作假设是系统试图保留缓存的文件数据,这会导致内存碎片。最终,当请求新内存时,即使大多数内存仍然“可用”,也会执行交换。

因此,我们转向改变Linux环境围绕文件缓存的行为的方法,并找到了这篇文章。在python中打开h5文件或我们通过numpy memmap访问的部分文件时,有没有办法调用POSIX_FADV_DONTNEED标志,这样缓存的累积就不会发生?在我们的用例中,我们很长一段时间内不会重新访问该特定文件位置(直到我们访问文件的所有其他剩余“切片”)

共有1个答案

朱天逸
2023-03-14

您可以使用操作系统。posix\u fadvise告诉操作系统如何使用您计划加载的区域。这自然需要一些低级的调整来确定文件描述符,并了解您计划读取的区域。

获取文件描述符的最简单方法是自己提供:

pf = open(tv_path, 'rb')
f = h5py.File(pf, 'r')

您现在可以设置建议。对于整个文件:

os.posix_fadvise(os.fileno(pf), 0, f.id.get_filesize(), os.POSIX_FADV_DONTNEED)

或对于特定数据集:

os.posix_fadvise(os.fileno(pf), hdf5_event_data.id.get_offset(),
                 hdf5_event_data.id.get_storage_size(), os.POSIX_FADV_DONTNEED)

其他要看的东西

H5py有自己的块缓存。您可能想尝试关闭此功能:

f = h5py.File(..., rdcc_nbytes=0)

作为替代方案,您可能希望尝试使用h5py中提供的其他驱动程序之一,如“sec2”:

f = h5py.File(..., driver='sec2')
 类似资料:
  • 我认为这些信息在开始的时候真的很重要,但是后来就没有用了。它实际上使读取和调试的情况变得更糟。 I tensorflow/流执行器/dso加载器。cc:128]已成功打开CUDA库libcublas。所以8.0本地I tensorflow/流执行器/dso加载器。抄送:119]无法打开CUDA库libcudnn。所以LD_库路径:I tensorflow/stream_executor/cuda/

  • 问题内容: 有没有办法编译一个node.js应用程序? 问题答案: 我可能已经很晚了,但是您可以使用“ nexe”模块在一个可执行文件中编译nodejs +您的脚本:https : //github.com/crcn/nexe

  • 问题内容: 假设我有一个使用lambda表达式(闭包)定义的对象列表。有没有一种方法可以检查它们以便进行比较? 我最感兴趣的代码是 完整的代码是 似乎唯一的解决方案是将每个lambda定义为一个字段,并且仅使用这些字段。如果要打印出称为的方法,最好使用。lambda表达式有更好的方法吗? 此外,是否可以打印lambda并获得人类可读的内容?如果你打印而不是 得到类似的东西 甚至使用和方法。 问题答

  • 我有一个简单的模块化javafx应用程序。 我用 这将创建mods目录 然后,我使用命令创建运行时映像 这将在hellofx目录中创建运行时映像 现在我使用jpackage命令来创建Windows安装程序。在目录中,我有一个应用程序的图标。 此图标用于已安装的应用程序,但有没有办法为安装程序文件本身创建图标?名为HelloFX-1.0的安装程序文件没有图标。有没有办法将jpack配置为也更改此文件

  • 我想获取属于一个节点的所有标签,如果SDN4.0中有一种方法可以在一个查询中实现这一点吗? 例如,我当前的回购协议如下 有没有反正我可以简单地 检索此账本节点的所有标签。 这本书的课程是 是的,默认情况下,我的Book节点应该有两个标签和。由于我在回购中有一个更新方法来添加另一个标签。无论如何,我可以找回这本书与所有3个标签? 谢啦

  • 有没有办法阻止刷卡手势打开抽屉。一、 我累了:抽屉。setDrawerLockMode(抽屉布局。LOCK\u MODE\u LOCKED\u CLOSED) 然而,有了这个,我甚至不能通过点击图标打开视图。我只需要禁用打开它的手势。