|
| 1 | +open Multicore_bench |
| 2 | + |
| 3 | +let run_one ~budgetf ~n_domains ~approach () = |
| 4 | + let counter = Atomic.make 0 |> Multicore_magic.copy_as_padded in |
| 5 | + |
| 6 | + let n_ops = 100 * Util.iter_factor in |
| 7 | + |
| 8 | + let n_ops_todo = Atomic.make 0 |> Multicore_magic.copy_as_padded in |
| 9 | + |
| 10 | + let init _ = Atomic.set n_ops_todo n_ops in |
| 11 | + let work _ () = |
| 12 | + match approach with |
| 13 | + | `Incr -> |
| 14 | + let rec work () = |
| 15 | + let n = Util.alloc n_ops_todo in |
| 16 | + if n <> 0 then |
| 17 | + let rec loop n = |
| 18 | + if 0 < n then begin |
| 19 | + Atomic.incr counter; |
| 20 | + loop (n - 1) |
| 21 | + end |
| 22 | + else work () |
| 23 | + in |
| 24 | + loop n |
| 25 | + in |
| 26 | + work () |
| 27 | + | `Cas -> |
| 28 | + let rec work () = |
| 29 | + let n = Util.alloc n_ops_todo in |
| 30 | + if n <> 0 then |
| 31 | + let rec loop n = |
| 32 | + if 0 < n then begin |
| 33 | + let v = Atomic.get counter in |
| 34 | + let success = Atomic.compare_and_set counter v (v + 1) in |
| 35 | + loop (n - Bool.to_int success) |
| 36 | + end |
| 37 | + else work () |
| 38 | + in |
| 39 | + loop n |
| 40 | + in |
| 41 | + work () |
| 42 | + | `Cas_backoff -> |
| 43 | + let rec work () = |
| 44 | + let n = Util.alloc n_ops_todo in |
| 45 | + if n <> 0 then |
| 46 | + let rec loop n backoff = |
| 47 | + if 0 < n then begin |
| 48 | + let v = Atomic.get counter in |
| 49 | + if Atomic.compare_and_set counter v (v + 1) then |
| 50 | + loop (n - 1) Backoff.default |
| 51 | + else loop n (Backoff.once backoff) |
| 52 | + end |
| 53 | + else work () |
| 54 | + in |
| 55 | + loop n Backoff.default |
| 56 | + in |
| 57 | + work () |
| 58 | + in |
| 59 | + |
| 60 | + let config = |
| 61 | + Printf.sprintf "%s, %d domains" |
| 62 | + (match approach with |
| 63 | + | `Incr -> "Incr" |
| 64 | + | `Cas -> "CAS" |
| 65 | + | `Cas_backoff -> "CAS with backoff") |
| 66 | + n_domains |
| 67 | + in |
| 68 | + Times.record ~budgetf ~n_domains ~init ~work () |
| 69 | + |> Times.to_thruput_metrics ~n:n_ops ~singular:"op" ~config |
| 70 | + |
| 71 | +let run_suite ~budgetf = |
| 72 | + Util.cross [ `Incr; `Cas; `Cas_backoff ] [ 1; 2; 4; 8 ] |
| 73 | + |> List.concat_map @@ fun (approach, n_domains) -> |
| 74 | + if Domain.recommended_domain_count () < n_domains then [] |
| 75 | + else run_one ~budgetf ~n_domains ~approach () |
0 commit comments