2017-03-12 27 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

相關問題