2017-03-12 2 views
0

Ich möchte eine Zeichenkette aus einem OCaml-Programm so effizient wie möglich in eine mmap 'ed-Speicherregion (erhalten über Genarray.file_map) kopieren. Mein Ziel ist es, anderen Prozessen das Lesen von diesem gemeinsamen Speicher zu ermöglichen, während der OCaml-Prozess läuft, mit minimalem Overhead (ich brauche keine vollständigen Nebenläufigkeitsfunktionen, es gibt nur einen Schreiber und einen Leser).Effizientes Kopieren von Zeichenketten in mmap-Position

Ich habe versucht, das Kopieren von Zeichen pro Zeichen, wie im folgenden Code-Schnipsel (wo ich die ersten 255 Zeichen der Zeichenfolge kopieren s):

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) 

aber das ist sehr ineffizient: selbst bei einem relativ kleinen Eingang, es dauert schon 3 mal länger auszuführen als ohne mmap.

Gibt es einen besseren Weg, es zu tun? Idealerweise möchte ich zu viele Abhängigkeiten vermeiden, z. Jane Street core.

Antwort

1

Das Bigarray-Modul bietet nur blit zwischen Bigarrays. Wenn der zusätzliche Overhead tatsächlich auf das Verhalten von mmapped-Speicher zurückzuführen ist, können Sie versuchen, zuerst von der Zeichenfolge in ein Bigarray zu kopieren und dann vom Bigarray in das mmapped-Ziel zu blittieren. (Um vom mmapped-Array zu lesen, könnten Sie das inverse tun.)

Die einzige andere Sache, die ich vorstellen kann, ist die Übertragungen in C (mit memcpy()) zu kodieren und sie als externe Funktionen zu nennen.

+0

Danke für die Vorschläge, obwohl die Verwendung von 'Blit' nicht viel geändert hat. 'memcpy' arbeitete besser, aber immer noch zu langsam für meine Zwecke. Das ursprüngliche Programm läuft in 0.6s; mit 'Genarray.Bigarray' dauert es 2.1s. Mit einer C-Bindung, die "mmap" und "memcpy" macht, sind es 1.4s. Es gibt also nicht viel zu tun, denke ich. – anol

+0

cstruct hat einige effiziente Funktionen zum Kopieren zwischen Strings/Bigarrays: https://github.com/mirage/ocaml-cstruct/blob/master/lib/cstruct.mli – hcarty

Verwandte Themen