Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
4ce972d
initial commit, update Dllist with vector library
Lucccyo May 23, 2022
0f43343
dllist with dynamics arrays -- started
Lucccyo May 24, 2022
3b27ee7
Dllist changed with external contents array
Lucccyo May 25, 2022
dc078a6
new dllist implementation
pascutto May 25, 2022
a64d09a
update lfu to work with dllist -> bugs to correct
Lucccyo May 25, 2022
9d1ab1e
add display
Lucccyo May 25, 2022
a290dff
wip
pascutto May 25, 2022
f73e068
final bugfix
pascutto May 27, 2022
bed3a5e
bug fixed
Lucccyo May 27, 2022
e30ba01
bug fixed
Lucccyo May 27, 2022
e36e6d3
first commit
Lucccyo May 27, 2022
5ec36da
add pp to bench
Lucccyo May 27, 2022
90f6491
match bench on differents instances id
Lucccyo May 27, 2022
90fc0fe
add mtime lib and counters
Lucccyo May 27, 2022
1eb7957
functorize replay
Lucccyo May 27, 2022
2fd8598
cli for replay
Lucccyo May 27, 2022
cd43db5
update bench
Lucccyo May 31, 2022
dda6030
add makefile
Lucccyo May 31, 2022
1804d5c
add makefile
Lucccyo May 31, 2022
9ce2a24
add libraries in opam file
Lucccyo May 31, 2022
51e661e
remove cache arg to dune command
Lucccyo May 31, 2022
a657dd1
change branch name
Lucccyo May 31, 2022
b4f62cd
:)
Lucccyo May 31, 2022
3c35d5c
Merge pull request #3 from Lucccyo/brench
Lucccyo May 31, 2022
36a8dbc
test
Lucccyo May 31, 2022
c84b1c0
a
Lucccyo May 31, 2022
b9e874d
a
Lucccyo May 31, 2022
77679bf
a
Lucccyo May 31, 2022
83a108d
r
Lucccyo May 31, 2022
4efc89f
a
Lucccyo May 31, 2022
a5e7bb5
k
Lucccyo May 31, 2022
f2a73dc
a
Lucccyo May 31, 2022
c17fa71
c
Lucccyo May 31, 2022
e25f73b
c
Lucccyo May 31, 2022
1c1ebaa
p
Lucccyo May 31, 2022
1fae7f8
m
Lucccyo May 31, 2022
0a8c1f8
lib
Lucccyo May 31, 2022
ecbb91a
az
Lucccyo May 31, 2022
1cff6f7
dl external trace
Lucccyo May 31, 2022
545d055
test
Lucccyo May 31, 2022
1781eda
flag
Lucccyo May 31, 2022
e7134f8
toto
Lucccyo May 31, 2022
290e191
last tests
Lucccyo May 31, 2022
20a1551
i
Lucccyo May 31, 2022
767b73e
i
Lucccyo May 31, 2022
187a24f
i
Lucccyo May 31, 2022
c5181a1
i
Lucccyo May 31, 2022
d7204b2
test wget
Lucccyo Jun 1, 2022
3096a34
test wget
Lucccyo Jun 1, 2022
52a7617
test wget
Lucccyo Jun 1, 2022
4d0a5c5
test wget
Lucccyo Jun 1, 2022
09ffec2
test wget
Lucccyo Jun 1, 2022
62a9f41
clean v1
Lucccyo Jun 1, 2022
34e3e0f
clean v2
Lucccyo Jun 1, 2022
3050737
clean v2
Lucccyo Jun 1, 2022
0f50fea
t
Lucccyo Jun 1, 2022
cde81cd
differenciate cache strats
Lucccyo Jun 1, 2022
b17f3a1
differenciate cache strats
Lucccyo Jun 1, 2022
e1d7416
ret
Lucccyo Jun 1, 2022
6c0d2b3
a
Lucccyo Jun 1, 2022
ea69b72
y
Lucccyo Jun 1, 2022
e1d1d25
r
Lucccyo Jun 1, 2022
f5e6037
h
Lucccyo Jun 1, 2022
3d5ca26
wow
Lucccyo Jun 2, 2022
1879115
o
Lucccyo Jun 2, 2022
8391b7b
haha
Lucccyo Jun 2, 2022
489c957
aleatoire
Lucccyo Jun 2, 2022
d4d40ee
:)
Lucccyo Jun 2, 2022
0008efd
:s
Lucccyo Jun 2, 2022
90c26e3
>:c <- fâché car pas de glace
Lucccyo Jun 2, 2022
bbc863a
il est triste
Lucccyo Jun 2, 2022
ec5a052
cha
Lucccyo Jun 2, 2022
566735b
o
Lucccyo Jun 2, 2022
1a90cd8
youpiii
Lucccyo Jun 2, 2022
98ca858
youpi deux
Lucccyo Jun 2, 2022
5fe13c3
the
Lucccyo Jun 2, 2022
70b6baf
test
Lucccyo Jun 2, 2022
402f6bc
re
Lucccyo Jun 2, 2022
9e76cbf
c
Lucccyo Jun 2, 2022
20d3afc
c
Lucccyo Jun 2, 2022
d4f8c83
end
Lucccyo Jun 2, 2022
a874f14
Merge pull request #4 from Lucccyo/brench
Lucccyo Jun 2, 2022
2ebdff2
added first line of gospel in lfu interface
Lucccyo Jun 24, 2022
b70a895
correct lfu contracts, need to comment Format module use in Stats.mli
Lucccyo Jun 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.PHONY: bench
bench:
sudo apt-get install wget
wget --directory-prefix=./trace http://data.tarides.com/irmin/lru.trace
dune exec bench/replay.exe
12 changes: 12 additions & 0 deletions bench/dune
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
(executable
(modules main)
(name main)
(libraries bechamel bechamel-notty notty.unix lru cachecache))

(executable
(modules
lru_trace_definition
replay
trace_auto_file_format_intf
trace_auto_file_format)
(preprocess
(pps ppx_repr))
(name replay)
(libraries cachecache fmt ppx_repr repr mtime mtime.clock.os cmdliner))

(alias
(name runtest)
(package cachecache-bench)
Expand Down
29 changes: 29 additions & 0 deletions bench/lru_trace_definition.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
(** File format of a trace listing the interactions with repr's LRU *)

module V0 = struct
let version = 0

type header = { instance_count : int } [@@deriving repr]

type op = Add of string | Find of string | Mem of string | Clear
[@@deriving repr]

type row = { instance_id : int; op : op } [@@deriving repr]
end

module Latest = V0
include Latest

include Trace_auto_file_format.Make (struct
module Latest = Latest

let magic = Trace_auto_file_format.Magic.of_string "LRUtrace"

let get_version_converter = function
| 0 ->
Trace_auto_file_format.create_version_converter ~header_t:V0.header_t
~row_t:V0.row_t ~upgrade_header:Fun.id ~upgrade_row:Fun.id
| i ->
let msg = Fmt.str "Unknown Raw_actions_trace version %d" i in
failwith msg
end)
120 changes: 120 additions & 0 deletions bench/replay.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
type span = Mtime.span

let span_t = Repr.map Repr.float (fun _ -> assert false) Mtime.Span.to_s

type stats = {
mutable add : int;
mutable mem : int;
mutable find : int;
mutable hit : int;
mutable miss : int;
mutable add_span : float;
mutable mem_span : float;
mutable find_span : float;
mutable total_runtime_span : float;
}
[@@deriving repr ~pp]

module K = struct
include String

let hash = Hashtbl.hash
end

let pr_bench test_name metrics =
Format.printf {|{"results": [{"name": "%s", "metrics": [%s]}]}@.|} test_name
metrics

let metrics metric_name value =
Printf.sprintf {|{"name": "%s", "value": %f, "units": "ms"}|} metric_name
value

let mtime s counter (f : unit -> unit) =
let t = Mtime_clock.count counter in
f ();
let t =
Mtime.Span.to_ms (Mtime.Span.abs_diff (Mtime_clock.count counter) t)
in
s.total_runtime_span <- s.total_runtime_span +. t;
t

module Make (Cache : Cachecache.S.Cache with type key = K.t) = struct
let bench cap =
let stats =
{
add = 0;
mem = 0;
find = 0;
hit = 0;
miss = 0;
add_span = 0.;
mem_span = 0.;
find_span = 0.;
total_runtime_span = 0.;
}
in
let open Lru_trace_definition in
let _, { instance_count }, seq = open_reader "./trace/lru.trace" in
let caches = List.init instance_count (fun _ -> Cache.v cap) in
let counter = Mtime_clock.counter () in
Seq.iter
(fun { instance_id; op } ->
let cache = List.nth caches instance_id in
match op with
| Add k ->
stats.add_span <-
stats.add_span +. mtime stats counter (Cache.replace cache k);
stats.add <- stats.add + 1
| Find k ->
stats.find_span <-
stats.find_span
+. mtime stats counter (fun _ -> ignore (Cache.find_opt cache k));
stats.find <- stats.find + 1
| Mem k ->
let b = Cache.mem cache k in
stats.mem_span <-
stats.mem_span +. mtime stats counter (fun _ -> ignore b);
if b then stats.hit <- stats.hit + 1
else stats.miss <- stats.miss + 1;
stats.mem <- stats.mem + 1
| _ -> assert false)
seq;
stats
end

include Cachecache.Lru.Make (K)
module Lru = Cachecache.Lru.Make (K)
module Lfu = Cachecache.Lfu.Make (K)
module Bench_lru = Make (Lru)
module Bench_lfu = Make (Lfu)

let () =
let t = [| 1000; 10000; 100000 |] in
for _ = 0 to 2 do
for i = 0 to Array.length t - 1 do
Fmt.pr "cap = %d\n" t.(i);
let lru_stats = Bench_lru.bench t.(i) in
let lfu_stats = Bench_lfu.bench t.(i) in
pr_bench "add"
(metrics "add/lru" lru_stats.add_span
^ ","
^ metrics "add/lfu" lfu_stats.add_span);
pr_bench "find"
(metrics "find/lru" lru_stats.find_span
^ ","
^ metrics "find/lfu" lfu_stats.find_span);
pr_bench "total_runtime"
(metrics "total_runtime/lru" lru_stats.total_runtime_span
^ ","
^ metrics "total_runtime/lfu" lfu_stats.total_runtime_span);
let str_cap = string_of_int t.(i) in
pr_bench "lfu" (metrics ("add/" ^ str_cap) lfu_stats.add_span);
pr_bench "lfu" (metrics ("find/" ^ str_cap) lfu_stats.find_span);
pr_bench "lfu"
(metrics ("total_runtime/" ^ str_cap) lfu_stats.total_runtime_span);
pr_bench "lru" (metrics ("add/" ^ str_cap) lru_stats.add_span);
pr_bench "lru" (metrics ("find/" ^ str_cap) lru_stats.find_span);
pr_bench "lru"
(metrics ("total_runtime/" ^ str_cap) lru_stats.total_runtime_span)
done
done
213 changes: 213 additions & 0 deletions bench/trace_auto_file_format.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2021-2022 Tarides <contact@tarides.com> *)
(* *)
(* Permission is hereby granted, free of charge, to any person obtaining a *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
(* and/or sell copies of the Software, and to permit persons to whom the *)
(* Software is furnished to do so, subject to the following conditions: *)
(* *)
(* The above copyright notice and this permission notice shall be included *)
(* in all copies or substantial portions of the Software. *)
(* *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
(* DEALINGS IN THE SOFTWARE. *)
(* *)
(*****************************************************************************)

include Trace_auto_file_format_intf

type ('latest_header, 'latest_row, 'header, 'row) version_converter' = {
header_t : 'header Repr.ty;
row_t : 'row Repr.ty;
upgrade_header : 'header -> 'latest_header;
upgrade_row : 'row -> 'latest_row;
}
(** Contains everything needed to read a file as if it is written using the
lastest version. *)

(** A box containing the above record *)
type (_, _) version_converter =
| Version_converter :
('latest_header, 'latest_row, 'header, 'row) version_converter'
-> ('latest_header, 'latest_row) version_converter

let create_version_converter :
header_t:'header Repr.ty ->
row_t:'row Repr.ty ->
upgrade_header:('header -> 'latest_header) ->
upgrade_row:('row -> 'latest_row) ->
('latest_header, 'latest_row) version_converter =
fun ~header_t ~row_t ~upgrade_header ~upgrade_row ->
Version_converter { header_t; row_t; upgrade_header; upgrade_row }

module Magic : MAGIC = struct
type t = string

let of_string s =
if String.length s <> 8 then
invalid_arg "Magic.of_string, string should have 8 chars";
s

let to_string s = s
let pp ppf s = Format.fprintf ppf "%s" (String.escaped s)
end

module type FILE_FORMAT =
FILE_FORMAT
with type magic := Magic.t
with type ('a, 'b) version_converter := ('a, 'b) version_converter

module type S =
S
with type File_format.magic := Magic.t
with type ('a, 'b) File_format.version_converter :=
('a, 'b) version_converter

(** Variable size integer. Very similar to what can be found in
"repr/type_binary.ml", but working straight off channels. [Var_int.read_exn]
reads the chars one by one from the provided [chan]. The recursion stops as
soon as a read char has its 8th bit equal to [0]. [Var_int.write] could be
implemented using [Repr.encode_bin int], but since [read_exn] can't be
implemented using repr, [write] isn't either. *)
module Var_int = struct
let chars =
Array.init 256 (fun i -> Bytes.unsafe_to_string (Bytes.make 1 (Char.chr i)))

let write : int -> out_channel -> unit =
let int i k =
let rec aux n k =
if n >= 0 && n < 128 then k chars.(n)
else
let out = 128 lor (n land 127) in
k chars.(out);
aux (n lsr 7) k
in
aux i k
in
fun i chan -> int i (output_string chan)

let read_exn : in_channel -> int =
fun chan ->
let max_bits = Sys.word_size - 1 in
let rec aux n p =
let () =
if p >= max_bits then raise (failwith "Failed to decode varint")
in
let i = input_char chan |> Char.code in
let n = n + ((i land 127) lsl p) in
if i >= 0 && i < 128 then n else aux n (p + 7)
in
aux 0 0
end

module Make (Ff : FILE_FORMAT) = struct
module File_format = Ff

let decode_i32 = Repr.(decode_bin int32 |> unstage)
let encode_i32 = Repr.(encode_bin int32 |> unstage)
let encode_lheader = Repr.(encode_bin Ff.Latest.header_t |> unstage)
let encode_lrow = Repr.(encode_bin Ff.Latest.row_t |> unstage)

let read_with_prefix_exn : (string -> int ref -> 'a) -> in_channel -> 'a =
fun decode chan ->
(* First read the prefix *)
let len = Var_int.read_exn chan in
(* Then read the repr. *)
let offset_ref = ref 0 in
let v =
(* This could fail if [len] is not long enough for repr (corruption) *)
decode (really_input_string chan len) offset_ref
in
let () =
if len <> !offset_ref then
let msg =
Fmt.str
"A value read in the Trace was expected to take %d bytes, but it \
took only %d."
len !offset_ref
in
raise (failwith msg)
in
v

let decoded_seq_of_encoded_chan_with_prefixes :
'a Repr.ty -> in_channel -> 'a Seq.t =
fun repr chan ->
let decode = Repr.decode_bin repr |> Repr.unstage in
let produce_row () =
try
let row = read_with_prefix_exn decode chan in
Some (row, ())
with End_of_file -> None
in
Seq.unfold produce_row ()

let open_reader : string -> int * Ff.Latest.header * Ff.Latest.row Seq.t =
fun path ->
let chan = open_in_bin path in
let len = LargeFile.in_channel_length chan in
let () =
if len < 12L then
let msg = Fmt.str "File '%s' should be at least 12 byte long" path in
raise (failwith msg)
in

let magic = Magic.of_string (really_input_string chan 8) in
let () =
if magic <> Ff.magic then
let msg =
Fmt.str "File '%s' has magic '%a'. Expected '%a'." path Magic.pp magic
Magic.pp Ff.magic
in
raise (failwith msg)
in

let offset_ref = ref 0 in
let version = decode_i32 (really_input_string chan 4) offset_ref in
let (Version_converter vc) =
assert (!offset_ref = 4);
Ff.get_version_converter (Int32.to_int version)
in

let header =
let decode_header = Repr.(decode_bin vc.header_t |> unstage) in
read_with_prefix_exn decode_header chan |> vc.upgrade_header
in
let seq =
decoded_seq_of_encoded_chan_with_prefixes vc.row_t chan
|> Seq.map vc.upgrade_row
in
(Int32.to_int version, header, seq)

type writer = { channel : out_channel; buffer : Buffer.t }

let create channel header =
let buffer = Buffer.create 0 in
output_string channel (Magic.to_string Ff.magic);
encode_i32 (Int32.of_int Ff.Latest.version) (output_string channel);
encode_lheader header (Buffer.add_string buffer);
Var_int.write (Buffer.length buffer) channel;
output_string channel (Buffer.contents buffer);
Buffer.clear buffer;
{ channel; buffer }

let create_file path header = create (open_out path) header

let append_row { channel; buffer; _ } row =
encode_lrow row (Buffer.add_string buffer);
Var_int.write (Buffer.length buffer) channel;
output_string channel (Buffer.contents buffer);
Buffer.clear buffer

let flush { channel; _ } = flush channel
let close { channel; _ } = close_out channel
end
Loading