Skip to content

Commit 39fb873

Browse files
committed
Benchmark for Work_stealing_deque
1 parent 2884c70 commit 39fb873

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

bench/bench_ws_deque.ml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
open Multicore_bench
2+
module Ws_deque = Saturn_lockfree.Work_stealing_deque.M
3+
4+
let run_one ~budgetf ?(n_domains = 1) () =
5+
let spawns =
6+
Array.init n_domains @@ fun _ -> ref 0 |> Multicore_magic.copy_as_padded
7+
in
8+
let deques = Array.init n_domains @@ fun _ -> Ws_deque.create () in
9+
let exit = ref false |> Multicore_magic.copy_as_padded in
10+
11+
let next i =
12+
let i = i + 1 in
13+
if i = n_domains then 0 else i
14+
in
15+
16+
let rec try_own own =
17+
match Ws_deque.pop (Array.unsafe_get deques own) with
18+
| work -> work
19+
| exception Exit -> try_steal own (next own)
20+
and try_steal own other =
21+
if other = own then raise_notrace Exit
22+
else
23+
match Ws_deque.steal (Array.unsafe_get deques other) with
24+
| work -> work
25+
| exception Exit -> try_steal own (next other)
26+
in
27+
let rec run own =
28+
match try_own own with
29+
| work ->
30+
work own;
31+
run own
32+
| exception Exit -> if not !exit then run own
33+
in
34+
35+
let spawn own work =
36+
incr (Array.unsafe_get spawns own);
37+
let promise = ref (Obj.magic exit) in
38+
Ws_deque.push (Array.unsafe_get deques own) (fun own -> promise := work own);
39+
promise
40+
in
41+
let rec await own promise =
42+
let x = !promise in
43+
if x == Obj.magic exit then begin
44+
begin
45+
match try_own own with exception Exit -> () | work -> work own
46+
end;
47+
await own promise
48+
end
49+
else x
50+
in
51+
52+
let rec fib n worker =
53+
if n < 2 then n
54+
else
55+
let n2 = spawn worker (fib (n - 2)) in
56+
let n1 = fib (n - 1) worker in
57+
await worker n2 + n1
58+
in
59+
60+
let rec bits n = if n <= 1 then 0 else 1 + bits (n lsr 1) in
61+
62+
let init own =
63+
Array.unsafe_get spawns own := 0;
64+
if own = 0 then begin
65+
exit := false;
66+
let n = 29 + bits n_domains in
67+
spawn own (fun own ->
68+
fib n own |> ignore;
69+
exit := true)
70+
|> ignore
71+
end
72+
in
73+
let work own () = run own in
74+
75+
let config =
76+
Printf.sprintf "%d worker%s" n_domains (if n_domains = 1 then "" else "s")
77+
in
78+
let times = Times.record ~budgetf ~n_domains ~init ~work () in
79+
let n = Array.fold_left (fun n c -> n + !c) 0 spawns in
80+
Util.thruput_metrics ~n ~singular:"spawn" ~config times
81+
82+
let run_suite ~budgetf =
83+
[ 1; 2; 4; 8 ]
84+
|> List.concat_map @@ fun n_domains -> run_one ~budgetf ~n_domains ()

bench/main.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ let benchmarks =
66
("Saturn_lockfree Size", Bench_size.run_suite);
77
("Saturn_lockfree Skiplist", Bench_skiplist.run_suite);
88
("Saturn_lockfree Stack", Bench_stack.run_suite);
9+
("Saturn_lockfree Work_stealing_deque", Bench_ws_deque.run_suite);
910
("Stdlib Queue", Bench_stdlib_queue.run_suite);
1011
("Stdlib Stack", Bench_stdlib_stack.run_suite);
1112
]

0 commit comments

Comments
 (0)