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
.
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
cstruct hat einige effiziente Funktionen zum Kopieren zwischen Strings/Bigarrays: https://github.com/mirage/ocaml-cstruct/blob/master/lib/cstruct.mli – hcarty