Skip to content

Commit df39286

Browse files
committed
Add Util.generate_push_and_pop_sequence for benchmarking queues
1 parent 7b8120a commit df39286

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

lib/multicore_bench.mli

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,14 @@ module Util : sig
6363
?rate:Rate.t ->
6464
Times.t ->
6565
Yojson.Safe.t list
66+
67+
module Bits : sig
68+
type t
69+
70+
val create : unit -> t
71+
val push : t -> bool -> unit
72+
val iter : (bool -> unit) -> t -> unit
73+
end
74+
75+
val generate_push_and_pop_sequence : ?state:Random.State.t -> int -> Bits.t
6676
end

lib/util.ml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,57 @@ let thruput_metrics ~n ~singular ?(plural = singular ^ "s") ~config
3232
~description:(Printf.sprintf "Total number of %s processed" plural)
3333
~units:(Rate.to_mnemonic rate);
3434
]
35+
36+
module Bits = struct
37+
type t = { mutable bytes : Bytes.t; mutable length : int }
38+
39+
let create () = { bytes = Bytes.create 1; length = 0 }
40+
41+
let push t bool =
42+
let capacity = Bytes.length t.bytes lsl 3 in
43+
if t.length == capacity then
44+
t.bytes <- Bytes.extend t.bytes 0 (capacity lsr 3);
45+
let byte_i = t.length lsr 3 in
46+
let mask = 1 lsl (t.length land 7) in
47+
t.length <- t.length + 1;
48+
let byte = Char.code (Bytes.unsafe_get t.bytes byte_i) in
49+
let byte = if bool then byte lor mask else byte land lnot mask in
50+
Bytes.unsafe_set t.bytes byte_i (Char.chr byte)
51+
52+
let length t = t.length
53+
54+
let rec iter fn t i =
55+
let n = t.length in
56+
if i < n then begin
57+
let byte = Char.code (Bytes.unsafe_get t.bytes (i lsr 3)) in
58+
fn (0 <> byte land 1);
59+
if i + 1 < n then fn (0 <> byte land 2);
60+
if i + 2 < n then fn (0 <> byte land 4);
61+
if i + 3 < n then fn (0 <> byte land 8);
62+
if i + 4 < n then fn (0 <> byte land 16);
63+
if i + 5 < n then fn (0 <> byte land 32);
64+
if i + 6 < n then fn (0 <> byte land 64);
65+
if i + 7 < n then fn (0 <> byte land 128);
66+
iter fn t (i + 8)
67+
end
68+
69+
let iter fn t = iter fn t 0
70+
end
71+
72+
let generate_push_and_pop_sequence ?(state = Random.State.make_self_init ())
73+
n_msgs =
74+
let bits = Bits.create () in
75+
let rec loop length n_push n_pop =
76+
if 0 < n_push || 0 < n_pop then begin
77+
let push = Random.State.bool state && 0 < n_push in
78+
Bits.push bits push;
79+
loop
80+
(if push then length + 1 else if 0 < length then length - 1 else length)
81+
(n_push - Bool.to_int push)
82+
(n_pop - Bool.to_int ((not push) && 0 < length))
83+
end
84+
else length
85+
in
86+
let length = loop 0 n_msgs n_msgs in
87+
assert (length = 0);
88+
bits

0 commit comments

Comments
 (0)