OCaml Marshal 非常大的数据结构

OCaml Marshal very large data structure

我想通过网络发送一个非常大的 (~8GB) 数据结构,所以我使用 Marshal 模块将其转换为字节。

我的问题是内存加倍,因为我们需要存储两种表示形式(初始数据和编组数据)。

是否有一种简单的方法改为编组到流中?这将避免拥有初始数据结构的完整编组表示。

我想到了编组到一个 out_channel,在其中我打开了一个带有第二个线程的管道,并从主线程中的管道读取到 s Stream,但我想可能有一个更简单的解决方案。

谢谢!


编辑:回复评论:

在顶层:

let a = Array.make (1024*1024*1024) 0. ;; (* Takes 8GB of RAM *)
let data = Marshal.to_bytes a [Marshal.Closures] ;; (* Takes an extra 8GB *)

据我了解,MPI 只允许发送已知大小的数据包,而不是数据流。您可以实现自定义流类型,将传入的数据流拆分为恒定的小尺寸数据包(关闭时,您刷新缓冲区中剩余的所有内容)。

此外,您只能将任意长数据编组到一个通道,否则会占用太多space。

然后,您需要有一种方法将频道连接到流,这 AFAIK 不容易实现。也许您可以启动 antoer ocaml 进程:该进程将转换字节流(您可以将自定义流包装在 Stream.of_channel 上)并通过 MPI 发送它。主进程会将数据编组到进程的输入通道。

这不可能。您将必须修改 Marshal 模块以在它编组某些内容时流式传输数据,并在不先缓冲所有数据的情况下就地重建数据。

简而言之 运行 实现您自己的特定于您的数据的专用编组函数可能更简单。对于 8GiB 阵列,您可能希望切换到使用 BigArray,这样您就可以 send/recv 数据而无需复制它。

注意:一个 8GiB 的数组将使用 16GiB 如果 GC 曾经复制它,至少是临时的。