mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-06 03:05:30 -05:00
60 lines
1.6 KiB
OCaml
60 lines
1.6 KiB
OCaml
let ( let@ ) = ( @@ )
|
|
let spf = Printf.sprintf
|
|
|
|
let generate' chan =
|
|
for i = 2 to Int.max_int do
|
|
Moonpool.Chan.push chan i
|
|
done
|
|
|
|
let filter' in_chan out_chan prime =
|
|
let rec loop () =
|
|
let n = Moonpool.Chan.pop in_chan in
|
|
if n mod prime <> 0 then Moonpool.Chan.push out_chan n;
|
|
loop ()
|
|
in
|
|
loop ()
|
|
|
|
let main ~chan_size ~n ~on_prime () : unit =
|
|
let@ runner = Moonpool.Ws_pool.with_ () in
|
|
let@ () = Moonpool.Ws_pool.run_wait_block runner in
|
|
let primes = ref @@ Moonpool.Chan.create ~max_size:chan_size () in
|
|
Moonpool.run_async runner
|
|
(let chan = !primes in
|
|
fun () -> generate' chan);
|
|
|
|
for _i = 1 to n do
|
|
let prime = Moonpool.Chan.pop !primes in
|
|
on_prime prime;
|
|
let filtered_chan = Moonpool.Chan.create ~max_size:chan_size () in
|
|
Moonpool.run_async runner
|
|
(let in_chan = !primes in
|
|
fun () -> filter' in_chan filtered_chan prime);
|
|
primes := filtered_chan
|
|
done
|
|
|
|
let () =
|
|
let n = ref 10_000 in
|
|
let chan_size = ref 0 in
|
|
let time = ref true in
|
|
let opts =
|
|
[
|
|
"-n", Arg.Set_int n, " number of iterations";
|
|
"--no-time", Arg.Clear time, " do not compute time";
|
|
"--chan-size", Arg.Set_int chan_size, " channel size";
|
|
]
|
|
|> Arg.align
|
|
in
|
|
Arg.parse opts ignore "";
|
|
Printf.printf "computing %d primes\n%!" !n;
|
|
|
|
let t_start = Unix.gettimeofday () in
|
|
|
|
let n_primes = Atomic.make 0 in
|
|
main ~n:!n ~chan_size:!chan_size ~on_prime:(fun _ -> Atomic.incr n_primes) ();
|
|
|
|
let elapsed : float = Unix.gettimeofday () -. t_start in
|
|
Printf.printf "computed %d primes%s\n%!" (Atomic.get n_primes)
|
|
(if !time then
|
|
spf " in %.4fs" elapsed
|
|
else
|
|
"")
|