2017-03-12 5 views
0

OCamlプログラムの文字列をmmapのメモリ領域(Genarray.file_mapから取得)にできるだけ効率的にコピーしたいと思います。私の目的は、最小限のオーバーヘッドでOCamlプロセスが動作している間に他のプロセスがこの共有メモリから読み取ることができるようにすることです(完全な並行処理機能は必要ありません。文字列をmmapされた場所に効率的にコピーする

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) 

しかし、これは非常に非効率的である:

私は(私は最初の文字列sの255個の文字をコピーする)次のスニペットのように、文字ごとに文字をコピーしようとしたとしても、比較的小さな入力して、それをmmapがない場合よりも実行に3倍の時間がかかります。

良い方法がありますか?理想的には、あまりにも多くの依存関係を回避したいと思います。ジェーン・ストリートのcore

答えて

1

Bigarrayモジュールは、bigarrays間にblitしか提供しません。余分なオーバーヘッドが本当にmmappedメモリの動作に起因する場合は、最初に文字列からbigarrayにコピーしてから、bigarrayからmmappedターゲットにblitしてみてください。

私が考えることができる唯一のもう一つの点は、Cで転送をコード化して(memcpy()を使用して)外部関数として呼び出すことです。

+0

提案してくれてありがとうございますが、 'blit'を使ってもあまり変わっていません。 'memcpy'は良く機能しましたが、私の目的にはまだ遅すぎます。元のプログラムは0.6秒で実行されます。 'Genarray.Bigarray'では2.1秒かかります。 Cバインディングで 'mmap'と' memcpy'を実行すると1.4秒です。だからここでやることはあまりありません。 – anol

+0

cstructには、文字列/ bigarraysの間でコピーするためのいくつかの効率的な関数があります:https://github.com/mirage/ocaml-cstruct/blob/master/lib/cstruct.mli – hcarty

関連する問題