From 60f33b6acc0f0b6c8b46398868a65ab82b479686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= Date: Tue, 10 Oct 2023 23:47:44 +0100 Subject: [PATCH] print speeds WiP --- .../ezbechamel_alcotest_notty.ml | 31 +++++++++++++++++-- .../lib/concurrent/ezbechamel_concurrent.ml | 18 +++++++++++ .../lib/concurrent/ezbechamel_concurrent.mli | 5 +++ ocaml/tests/bench/pam/bench_pam.ml | 5 ++- 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/ocaml/tests/bench/lib/alcotest_notty/ezbechamel_alcotest_notty.ml b/ocaml/tests/bench/lib/alcotest_notty/ezbechamel_alcotest_notty.ml index 7859e4cbc4a..8f1ec594987 100644 --- a/ocaml/tests/bench/lib/alcotest_notty/ezbechamel_alcotest_notty.ml +++ b/ocaml/tests/bench/lib/alcotest_notty/ezbechamel_alcotest_notty.ml @@ -22,10 +22,15 @@ let dump_measure ppf m = open Ezbechamel_cli +(* this cannot be a Bechamel.Measure, because speed can't be averaged arithmetically, + would need to use a geometric mean + *) let output_notty t results = let open Notty_unix in let () = - List.iter (fun i -> Bechamel_notty.Unit.add i (Measure.unit i)) t.measures + List.iter (fun i -> + Bechamel_notty.Unit.add i (Measure.unit i) + ) t.measures in let window = @@ -38,11 +43,31 @@ let output_notty t results = img (window, results) |> eol |> output_image let output_text t results = - Format.printf "Measures: %a@." Fmt.Dump.(list dump_measure) t.measures ; + let time_measure, count_measure = + List.fold_left (fun (time_measure, count_measure) i -> + let u = Measure.unit i in + match u with + | "ns" -> (Some i, count_measure) + | "count" -> (time_measure, Some i) + | _ -> (time_measure, count_measure) + ) (None, None) t.measures + in + Format.printf "Measures: %a@." Fmt.Dump.(list dump_measure) t.measures ; Format.printf "%a@." (dump_hashtbl "results" (dump_hashtbl "result" Analyze.OLS.pp)) - results + results; + match time_measure, count_measure with + | Some t, Some c -> + let times = Hashtbl.find results (Measure.label t) + and counts = Hashtbl.find results (Measure.label c) in + (* TODO: should be able to query Ci95 from OLS.t *) + Hashtbl.iter (fun k ns -> + let ns = Analyze.OLS.estimates ns |> Option.get |> List.hd in + let count = Hashtbl.find counts k |> Analyze.OLS.estimates |> Option.get |> List.hd in + Format.printf "%s = %.3f operations/s@." k (count /. (ns *. 1e-9)) + ) times; + | _ -> () let save_to_file t results raw_results = let open Ezbechamel_cli in diff --git a/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.ml b/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.ml index aad6ed734e5..161c6a38bf9 100644 --- a/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.ml +++ b/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.ml @@ -8,6 +8,23 @@ 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. *) +module Operations = struct + let count = Atomic.make 0 + type witness = unit + let label () = "operations" + let unit () = "count" + let make () = () + let load () = () + let unload () = () + let get () = Atomic.get count |> float_of_int +end + +module Extension = struct + let operations = Bechamel.Measure.register (module Operations) +end + +let operations = Bechamel.Measure.instance (module Operations) Extension.operations + let semaphore () = Semaphore.Binary.make false let wait = Semaphore.Binary.acquire @@ -36,6 +53,7 @@ module Worker = struct try let () = Sys.opaque_identity (Bechamel.Staged.unstage run resource) in Atomic.set t.result ok; + Atomic.incr Operations.count; with e -> let bt = Printexc.get_raw_backtrace () in Atomic.set t.result (Some (Error (`Exn_trap (e, bt)))) diff --git a/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.mli b/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.mli index 3096d0231f6..55a0e6c75f9 100644 --- a/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.mli +++ b/ocaml/tests/bench/lib/concurrent/ezbechamel_concurrent.mli @@ -12,6 +12,11 @@ Worker {!mod:Threads} support for {!mod:Bechamel}. *) +val operations: Bechamel.Measure.witness +(** [operations] is the number of operations performed, potentially concurrently by [test_concurrently]. + This can be useful for deriving operations/s metrics. +*) + val test_concurrently : ?threads:int list -> allocate:(unit -> 'a) diff --git a/ocaml/tests/bench/pam/bench_pam.ml b/ocaml/tests/bench/pam/bench_pam.ml index db5775b7b21..cdb032e0447 100644 --- a/ocaml/tests/bench/pam/bench_pam.ml +++ b/ocaml/tests/bench/pam/bench_pam.ml @@ -16,6 +16,7 @@ open Bechamel let args = [1; 2; 4; 8; 16] + open Ezbechamel_concurrent let pam_start_stop () = @@ -59,8 +60,10 @@ let sleepfix_stop' (h, h') = let pam_authenticate' _ = Pam.authenticate username password +let measures = Toolkit.Instance.[Ezbechamel_concurrent.operations; monotonic_clock; minor_allocated ] + let () = - Ezbechamel_alcotest_notty.run + Ezbechamel_alcotest_notty.run ~measures [ Test.make ~name:"PAM start+stop" (Staged.stage pam_start_stop) ; Test.make ~name:"PAM start+run+stop" (Staged.stage pam_start_run_stop) ; Test.make ~name:"PAM authenticate (current)" (Staged.stage pam_authenticate)