2017-03-12 29 views
0

我想从OCaml程序中将字符串尽可能有效地复制到mmap'ed内存区域(通过Genarray.file_map获取)。我的目标是允许其他进程在OCaml进程运行时从此共享内存中读取,并且开销最小(我不需要完全并发功能,只有一个写入器和一个阅读器)。有效地将字符串复制到mmap的位置

我试图复制每个字符的字符,如在下面的代码段(其中I串s的前255个字符复制):

let fd = Unix.openfile "/tmp/foo" [Unix.O_RDWR; Unix.O_CREAT] 0o600 in 
let mmap = Bigarray.Genarray.map_file fd Bigarray.Char Bigarray.C_layout true 
    (Array.of_list [256]) 
in 
let n = min (String.length s - 1) 255 in 
for i = 0 to n do 
    Bigarray.Genarray.set mmap [|i|] (String.get s i) 
done; 
Bigarray.Genarray.set mmap [|n|] (Char.chr 0) 

但是,这是非常低效的:即使具有相对小的输入时,它已经比无mmap长3倍。

有没有更好的方法来做到这一点?理想情况下,我想避免太多依赖,例如简街的core

回答

1

Bigarray模块仅在bigarrays之间提供blit。如果额外的开销真的是由于mmapped内存的行为造成的,您可以尝试先从字符串复制到bigarray,然后从bigarray blit到mmapped目标。 (要从mmapped数组中读取,你可以做相反的处理。)

我能想到的唯一的另一件事是在C中使用代码传输(使用memcpy())并将它们作为外部函数调用。

+0

感谢您的建议,尽管使用'blit'没有太大的改变。 'memcpy'效果更好,但对于我的目的而言仍然太慢。原始程序运行在0.6s;与'Genarray.Bigarray',它需要2.1s。用C绑定做'mmap'和'memcpy',它是1.4s。所以我想这里没有太多的工作要做。 – anol

+0

cstruct有一些有效的函数用于在字符串/ bigarrays之间进行复制:https://github.com/mirage/ocaml-cstruct/blob/master/lib/cstruct.mli – hcarty

相关问题