我想通过网络发送非常大的数据结构(约8GB),因此我使用Marshal模块将其转换为Bytes。
我的问题是内存增加了一倍,因为我们需要存储两种表示形式(初始数据和封送处理的数据)。
是否有一种简单的方法将元帅编组到溪流中?这样可以避免对初始数据结构进行完整的Marshalled表示。
我想到了编组到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 *)
答案 0 :(得分:3)
不可能。您可能需要修改Marshal模块以在封送数据时流式传输数据,并在不首先缓冲所有数据的情况下就地重建数据。
在短期内,实现针对数据的自己的专门编组函数可能会更简单。对于8GiB阵列,您可能希望切换为使用BigArray,以便无需复制就可以发送/接收数据。
注意:如果GC复制了8GiB阵列,它将使用16GiB,至少是临时的。
答案 1 :(得分:1)
据我了解,MPI仅允许发送已知大小的数据包,而不发送数据流。您可以实现一种自定义流类型,将传入的数据流拆分为大小恒定的小数据包(关闭时,刷新缓冲区中剩余的所有内容)。
此外,您只能将任意长数据编组到通道,因为否则会占用太多空间。
然后,您需要一种方法将频道连接到流,而AFAIK则不容易实现。也许您可以启动一个ocaml流程:该流程将转换字节流(您可以将自定义流包装在Stream.of_channel
上)并通过MPI发送。主流程会将数据编组到流程的输入通道。