moonpool/test/t_fib_rec.ml
2023-10-28 13:19:44 -04:00

85 lines
2.1 KiB
OCaml

open! Moonpool
let ( let@ ) = ( @@ )
let rec fib_direct x =
if x <= 1 then
1
else
fib_direct (x - 1) + fib_direct (x - 2)
let n_calls_fib_direct = Atomic.make 0
let rec fib ~on x : int Fut.t =
if x <= 18 then
Fut.spawn ~on (fun () ->
Atomic.incr n_calls_fib_direct;
fib_direct x)
else
let open Fut.Infix_local in
let+ t1 = fib ~on (x - 1) and+ t2 = fib ~on (x - 2) in
t1 + t2
let () = assert (List.init 10 fib_direct = [ 1; 1; 2; 3; 5; 8; 13; 21; 34; 55 ])
let fib_40 : int lazy_t =
lazy
(let@ _sp = Trace.with_span ~__FILE__ ~__LINE__ "fib40" in
let pool = Fifo_pool.create ~num_threads:8 () in
let r = fib ~on:pool 40 |> Fut.wait_block_exn in
Ws_pool.shutdown pool;
r)
let run_test ~pool () =
let@ _sp = Trace.with_span ~__FILE__ ~__LINE__ "run-test" in
let (lazy fib_40) = fib_40 in
assert (
List.init 10 (fib ~on:pool)
|> Fut.join_list |> Fut.wait_block_exn
= [ 1; 1; 2; 3; 5; 8; 13; 21; 34; 55 ]);
let n_fibs = 3 in
let fibs = Array.init n_fibs (fun _ -> fib ~on:pool 40) in
let res = Fut.join_array fibs |> Fut.wait_block in
assert (res = Ok (Array.make n_fibs fib_40))
let run_test_size ~size () =
Printf.printf "test pool(%d)\n%!" size;
let@ pool = Ws_pool.with_ ~num_threads:size () in
run_test ~pool ()
let run_test_fifo ~size () =
Printf.printf "test fifo(%d)\n%!" size;
let@ pool = Fifo_pool.with_ ~num_threads:size () in
run_test ~pool ()
let setup_counter () =
if Trace.enabled () then
ignore
(Thread.create
(fun () ->
while true do
Thread.delay 0.01;
Trace.counter_int "n-fib-direct" (Atomic.get n_calls_fib_direct)
done)
()
: Thread.t)
let () =
let@ () = Trace_tef.with_setup () in
setup_counter ();
let (lazy fib_40) = fib_40 in
Printf.printf "fib 40 = %d\n%!" fib_40;
run_test_fifo ~size:4 ();
List.iter (fun size -> run_test_size ~size ()) [ 1; 2; 4; 8 ];
(* now make sure we can do this with multiple pools in parallel *)
let jobs = Array.init 4 (fun _ -> Thread.create (run_test_size ~size:4) ()) in
Array.iter Thread.join jobs