Skip to content

Commit

Permalink
Optimize Pool_role fastpath (#6279)
Browse files Browse the repository at this point in the history
Before (measuring both unloaded, and loaded situation where other
threads are accessing the mutex):
```
Running benchmarks (no workloads)
╭────────────────────────────────────┬───────────────────────────┬───────────────────────────┬───────────────────────────╮
│name                                │  major-allocated          │  minor-allocated          │  monotonic-clock          │
├────────────────────────────────────┼───────────────────────────┼───────────────────────────┼───────────────────────────┤
│  Cached reads/Pool_role.is_master  │             0.0000 mjw/run│             4.0000 mnw/run│             23.6039 ns/run│
╰────────────────────────────────────┴───────────────────────────┴───────────────────────────┴───────────────────────────╯

Cached reads/Pool_role.is_master (ns):
 { monotonic-clock per run = 23.603889 (confidence: 23.644693 to 23.568067);
   r² = Some 0.999899 }

Running benchmarks (workloads)
╭────────────────────────────────────┬───────────────────────────┬───────────────────────────┬───────────────────────────╮
│name                                │  major-allocated          │  minor-allocated          │  monotonic-clock          │
├────────────────────────────────────┼───────────────────────────┼───────────────────────────┼───────────────────────────┤
│  Cached reads/Pool_role.is_master  │             0.0000 mjw/run│             7.4201 mnw/run│             76.4067 ns/run│
╰────────────────────────────────────┴───────────────────────────┴───────────────────────────┴───────────────────────────╯

Cached reads/Pool_role.is_master (ns):
 { monotonic-clock per run = 76.406674 (confidence: 86.718075 to 66.336404);
   r² = Some 0.608131 }
```

After:
```

Running benchmarks (no workloads)
╭────────────────────────────────────┬───────────────────────────┬───────────────────────────┬───────────────────────────╮
│name                                │  major-allocated          │  minor-allocated          │  monotonic-clock          │
├────────────────────────────────────┼───────────────────────────┼───────────────────────────┼───────────────────────────┤
│  Cached reads/Pool_role.is_master  │             0.0000 mjw/run│             0.0000 mnw/run│              3.1256 ns/run│
╰────────────────────────────────────┴───────────────────────────┴───────────────────────────┴───────────────────────────╯

Cached reads/Pool_role.is_master (ns):
 { monotonic-clock per run = 3.125616 (confidence: 3.131412 to 3.120373);
   r² = Some 0.999885 }

Running benchmarks (workloads)
╭────────────────────────────────────┬───────────────────────────┬───────────────────────────┬───────────────────────────╮
│name                                │  major-allocated          │  minor-allocated          │  monotonic-clock          │
├────────────────────────────────────┼───────────────────────────┼───────────────────────────┼───────────────────────────┤
│  Cached reads/Pool_role.is_master  │             0.0000 mjw/run│             0.0000 mnw/run│              6.2872 ns/run│
╰────────────────────────────────────┴───────────────────────────┴───────────────────────────┴───────────────────────────╯

Cached reads/Pool_role.is_master (ns):
 { monotonic-clock per run = 6.287197 (confidence: 6.737363 to 5.830140);
   r² = Some 0.706843 }
```
  • Loading branch information
edwintorok authored Feb 7, 2025
2 parents 51897aa + b945e10 commit 71f64c8
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
14 changes: 14 additions & 0 deletions ocaml/tests/bench/bench_cached_reads.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
open Bechamel

let run () =
let _ : bool = Sys.opaque_identity (Pool_role.is_master ()) in
()

let mutex_workload =
Bechamel_simple_cli.thread_workload ~before:ignore ~after:ignore ~run

let benchmarks =
Test.make_grouped ~name:"Cached reads"
[Test.make ~name:"Pool_role.is_master" (Staged.stage Pool_role.is_master)]

let () = Bechamel_simple_cli.cli ~workloads:[mutex_workload] benchmarks
2 changes: 1 addition & 1 deletion ocaml/tests/bench/dune
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(executables
(names bench_tracing bench_uuid bench_throttle2)
(names bench_tracing bench_uuid bench_throttle2 bench_cached_reads)
(libraries tracing bechamel bechamel-notty notty.unix tracing_export threads.posix fmt notty uuid xapi_aux tests_common log xapi_internal)
)
33 changes: 17 additions & 16 deletions ocaml/xapi-aux/pool_role.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,19 @@ type t =
(* IP address *)
| Broken

let role = ref None
let role = Atomic.make None

let role_unit_tests = ref false
let role_unit_tests = Atomic.make false

let role_m = Mutex.create ()

let with_pool_role_lock f = Xapi_stdext_threads.Threadext.Mutex.execute role_m f

let set_pool_role_for_test () =
with_pool_role_lock (fun _ ->
role := Some Master ;
role_unit_tests := true
)
Atomic.set role (Some Master) ;
Atomic.set role_unit_tests true

let is_unit_test () = with_pool_role_lock (fun _ -> !role_unit_tests)
let is_unit_test () = Atomic.get role_unit_tests

let string_of = function
| Master ->
Expand Down Expand Up @@ -80,15 +78,18 @@ let read_pool_role () =
)

let get_role () =
with_pool_role_lock (fun _ ->
match !role with
| Some x ->
x
| None ->
let r = read_pool_role () in
role := Some r ;
r
)
match Atomic.get role with
| Some x ->
x
| None ->
with_pool_role_lock (fun _ ->
match Atomic.get role with
| Some x ->
x
| None ->
let r = read_pool_role () in
Atomic.set role (Some r) ; r
)

let is_master () = get_role () = Master

Expand Down

0 comments on commit 71f64c8

Please # to comment.