Skip to content

Commit c775287

Browse files
author
David Scott
committed
xenvm benchmark supports --threads and --volumes
--volumes <n>: create and destroy <n> volumes --threads <t>: share the work over <t> background threads Signed-off-by: David Scott <[email protected]>
1 parent e3f5dac commit c775287

File tree

1 file changed

+67
-26
lines changed

1 file changed

+67
-26
lines changed

xenvm/xenvm.ml

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -164,37 +164,72 @@ let shutdown copts (vg_name,_) =
164164
lwt_while (fun () -> is_alive pid) (fun () -> Lwt_unix.sleep 1.0)
165165
in Lwt_main.run t
166166

167-
let benchmark copts (vg_name,_) =
167+
let benchmark copts (vg_name,_) volumes threads =
168168
let t =
169169
let creation_host = Unix.gethostname () in
170170
get_vg_info_t copts vg_name >>= fun info ->
171171
set_uri copts info;
172172
let mib = Int64.mul 1048576L 4L in
173-
let number = 1000 in
174-
let start = Unix.gettimeofday () in
175-
let rec fori test_name acc f = function
176-
| 0 -> return acc
177-
| n ->
178-
f n
179-
>>= fun () ->
180-
( if ((n * 100) / number) <> (((n + 1) * 100) / number)
181-
then stderr "%s %d %% complete\n%!" test_name (100 - (n * 100) / number)
182-
else return () ) >>= fun () ->
183-
fori test_name ((number - n, Unix.gettimeofday () -. start) :: acc) f (n - 1) in
184-
fori "Creating volumes" [] (fun i -> Client.create ~name:(Printf.sprintf "test-lv-%d" i) ~size:mib ~creation_host ~creation_time:(Unix.gettimeofday () |> Int64.of_float) ~tags:[]) number
185-
>>= fun creates ->
186-
let time = Unix.gettimeofday () -. start in
173+
174+
let start = ref (Unix.gettimeofday ()) in
175+
let n_pending = ref volumes in
176+
let m = Lwt_mutex.create () in
177+
let n_complete = ref 0 in
178+
let times = ref [] in
179+
let on_complete () =
180+
incr n_complete;
181+
let n = !n_complete in
182+
times := (n, Unix.gettimeofday () -. !start) :: !times;
183+
if ((n * 100) / volumes) <> (((n + 1) * 100) / volumes)
184+
then stderr "%d %% complete" ((n * 100) / volumes)
185+
else return () in
186+
let rec worker f =
187+
Lwt_mutex.with_lock m
188+
(fun () ->
189+
if !n_pending > 0 then begin
190+
decr n_pending;
191+
return (Some (volumes - !n_pending))
192+
end else return None)
193+
>>= function
194+
| Some n ->
195+
f n
196+
>>= fun () ->
197+
on_complete ()
198+
>>= fun () ->
199+
worker f
200+
| None ->
201+
return () in
202+
203+
let create n =
204+
Client.create ~name:(Printf.sprintf "test-lv-%d" n) ~size:mib ~creation_host ~creation_time:(Unix.gettimeofday () |> Int64.of_float) ~tags:[] in
205+
let destroy n =
206+
Client.remove ~name:(Printf.sprintf "test-lv-%d" n) in
207+
208+
let rec mkints = function
209+
| 0 -> []
210+
| n -> n :: (mkints (n - 1)) in
211+
let creators = List.map (fun _ -> worker create) (mkints threads) in
212+
Lwt.join creators
213+
>>= fun () ->
214+
187215
let oc = open_out "benchmark.dat" in
188-
List.iter (fun (n, t) -> Printf.fprintf oc "%d %f\n" n t) (List.rev creates);
189-
Printf.fprintf oc "# %d creates in %.1f s\n" number time;
190-
Printf.fprintf oc "# Average %.1f /sec\n" (float_of_int number /. time);
191-
let start = Unix.gettimeofday () in
192-
fori "Removing volumes" [] (fun i -> Client.remove ~name:(Printf.sprintf "test-lv-%d" i)) number
193-
>>= fun destroys ->
194-
let time = Unix.gettimeofday () -. start in
195-
List.iter (fun (n, t) -> Printf.fprintf oc "%d %f\n" (number + n) t) (List.rev destroys);
196-
Printf.fprintf oc "# %d destroys in %.1f s\n" number time;
197-
Printf.fprintf oc "# Average %.1f /sec\n" (float_of_int number /. time);
216+
let time = Unix.gettimeofday () -. !start in
217+
List.iter (fun (n, t) -> Printf.fprintf oc "%d %f\n" n t) (List.rev !times);
218+
Printf.fprintf oc "# %d creates in %.1f s\n" volumes time;
219+
Printf.fprintf oc "# Average %.1f /sec\n" (float_of_int volumes /. time);
220+
221+
start := Unix.gettimeofday ();
222+
n_pending := volumes;
223+
n_complete := 0;
224+
times := [];
225+
226+
let destroyers = List.map (fun _ -> worker destroy) (mkints threads) in
227+
Lwt.join destroyers
228+
>>= fun () ->
229+
let time = Unix.gettimeofday () -. !start in
230+
List.iter (fun (n, t) -> Printf.fprintf oc "%d %f\n" (volumes + n) t) (List.rev !times);
231+
Printf.fprintf oc "# %d destroys in %.1f s\n" volumes time;
232+
Printf.fprintf oc "# Average %.1f /sec\n" (float_of_int volumes /. time);
198233
return () in
199234
Lwt_main.run t
200235

@@ -315,7 +350,13 @@ let benchmark_cmd =
315350
`S "DESCRIPTION";
316351
`P "Perform some microbenchmarks and print the results.";
317352
] in
318-
Term.(pure benchmark $ copts_t $ name_arg),
353+
let volumes_arg =
354+
let doc = "The number of logical volumes which should be created then destroyed." in
355+
Arg.(value & opt int 10000 & info [ "volumes"; "v" ] ~docv:"VOLUMES" ~doc) in
356+
let threads_arg =
357+
let doc = "The number of concurrent worker threads which should create then destroy the volumes." in
358+
Arg.(value & opt int 1 & info [ "threads"; "t" ] ~docv:"THREADS" ~doc) in
359+
Term.(pure benchmark $ copts_t $ name_arg $ volumes_arg $ threads_arg),
319360
Term.info "benchmark" ~sdocs:copts_sect ~doc ~man
320361

321362
let default_cmd =

0 commit comments

Comments
 (0)