磁盘中巨大的矩阵状结构的小子集透明

时间:2014-06-17 18:31:13

标签: haskell on-disk

问题的简化版

我有一个巨大的矩阵式数据集,我们现在可以假装实际上是n - by - n矩阵存储在磁盘上n^2 IEEE-754加倍(请参阅下面关于如何简化的细节 - 这可能很重要。该文件大约为千兆字节,但在某个(纯)函数中,我只需要其中包含的元素n的顺序。究竟需要哪些元素是复杂的,而不是简单的切片。

我有什么选择从磁盘和计算中读取文件?最重要的是,我想把磁盘上的数据看作是在内存中(我当然准备向所有参考透明度的神发誓,磁盘上的数据不会改变)。我看过mmapfriends,但是一些粗略的测试表明这些似乎没有足够的自由记忆。

如果我需要对内存中保存多少文件进行细粒度控制,我是否必须将计算结合到IO上?


对磁盘数据的更诚实的描述

磁盘上的数据实际上并不像描述的那么简单。更接近事实的是:文件以32位整数n开头。然后,恰好n次出现以下情况:32位整数m_i> 0(1≤i≤n),接着是m_i IEEE-754双倍x_(i,1),…,x_(i, m_i)。 (所以,这是一个锯齿状的二维数组)。

在实践中,确定需要i的{​​{1}}和j在很大程度上取决于x_(i, j)。当使用mmap解决问题时,需要读取这么多m_i s似乎基本上将整个文件加载到内存中。问题是这一切似乎都停留在那里,我担心我必须将我的计算机拉入m_i以更好地控制释放这个记忆。

此外,“数据结构”实际上包含大量通过文件名参数化的文件。 在一起它们相当于一个千兆字节。


尝试更轻松,但可能更容易理解的问题版本

假设我在磁盘上有一些由IO元素组成的数据。纯Haskell函数需要n^2元素的顺序,但它们它们以复杂的方式依赖于值。我不想将整个文件加载到内存中,因为它很大。一种解决方案是将我的函数放入n monad并在需要时读出元素,但我称之为“放弃”。 mmap让我们将磁盘上的数据看作是在内存中,基本上是在操作系统的虚拟内存系统的帮助下进行懒惰的IO。这很好,但是由于确定需要哪些数据元素需要访问大量文件,因此mmap似乎在内存中保留了太多的文件。在实践中,我发现在使用mmap时,读取我需要确定的数据实际需要将整个文件加载到内存中。

我有哪些选择?

1 个答案:

答案 0 :(得分:1)

我建议您编写一个完全在IO中的接口,其中您的抽象类型包含Handle和有关数据整体结构的信息(可能是m_i s,如果你可以适应它们),并通过IO操作补充,通过在句柄中搜索来读出数据的精确位。

然后我会简单地将这个界面包装在一堆unsafePerformIO个调用中!从某种意义上说,这实际上就是mmap在幕后所做的事情。您只是以更明确的方式管理。

假设你无论如何都不担心"交换"你背后的文件,你可以得到一个你可以完全理解的界面,而它实际上是IO,必要时可以明确控制你需要的内存。