Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A handful of tentative performance improvements #295

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@
digestif
xmlm
(hc (>= 0.3))
(processor (>= 0.1))
dune-site)
(sites (share pyc) (share binc) (share libc)))
1 change: 1 addition & 0 deletions owi.opam
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ depends: [
"digestif"
"xmlm"
"hc" {>= "0.3"}
"processor" {>= "0.1"}
"dune-site"
]
build: [
Expand Down
6 changes: 3 additions & 3 deletions src/bin/owi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ let unsafe =

let workers =
let doc =
"number of workers for symbolic execution. Defaults to a machine-specific \
value given by the OCaml Domain.recommended_domain_count function."
"number of workers for symbolic execution. Defaults to the number of \
physical cores."
in
krtab marked this conversation as resolved.
Show resolved Hide resolved
Cmdliner.Arg.(
value
& opt int (Domain.recommended_domain_count ())
& opt int Processor.Query.core_count
& info [ "workers"; "w" ] ~doc ~absent:"n" )

let workspace =
Expand Down
15 changes: 14 additions & 1 deletion src/cmd/cmd_sym.ml
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,20 @@ let cmd profiling debug unsafe optimize workers no_stop_at_failure no_values
let pc = Choice.return (Ok ()) in
let result = List.fold_left (run_file ~unsafe ~optimize) pc files in
let thread : Thread.t = Thread.create () in
let results = Symbolic_choice.run ~workers result thread in
let res_queue = Wq.init () in
let callback = function
| Symbolic_choice.EVal (Ok ()), _ -> ()
| v -> Wq.push v res_queue
in
let join_handles =
Symbolic_choice.run ~workers result thread ~callback
~callback_init:(fun () -> Wq.make_pledge res_queue)
~callback_end:(fun () -> Wq.end_pledge res_queue)
in
let results =
Wq.read_as_seq res_queue ~finalizer:(fun () ->
Array.iter Domain.join join_handles )
in
let print_bug = function
| `ETrap (tr, model) ->
Format.pp_std "Trap: %s@\n" (Trap.to_string tr);
Expand Down
5 changes: 2 additions & 3 deletions src/data_structures/wq.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let make_pledge q =
let end_pledge q =
Mutex.lock q.mutex;
q.pledges <- q.pledges - 1;
Condition.broadcast q.cond;
if q.pledges = 0 then Condition.broadcast q.cond;
Mutex.unlock q.mutex

let rec read_as_seq (q : 'a t) ~finalizer : 'a Seq.t =
Expand All @@ -49,9 +49,8 @@ let rec read_as_seq (q : 'a t) ~finalizer : 'a Seq.t =

let push v q =
Mutex.lock q.mutex;
let was_empty = Queue.is_empty q.queue in
Queue.push v q.queue;
if was_empty then Condition.broadcast q.cond;
Condition.signal q.cond;
Mutex.unlock q.mutex

let fail q =
Expand Down
1 change: 1 addition & 0 deletions src/dune
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
menhirLib
ocaml_intrinsics
ppxlib
processor
sedlex
uutf
runtime_events
Expand Down
53 changes: 28 additions & 25 deletions src/symbolic/symbolic_choice.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ module CoreImpl : sig

type 'a run_result = ('a eval * Thread.t) Seq.t

val run : workers:int -> 'a t -> Thread.t -> 'a run_result
val run :
workers:int
-> 'a t
-> Thread.t
-> callback:('a eval * Thread.t -> unit)
-> callback_init:(unit -> unit)
-> callback_end:(unit -> unit)
-> unit Domain.t array
end = struct
module Schedulable = struct
(*
Expand Down Expand Up @@ -127,25 +134,19 @@ end = struct
*)
type ('a, 'wls) work_queue = ('a, 'wls) Schedulable.t Wq.t

type 'a res_queue = 'a Wq.t

type ('a, 'wls) t =
{ work_queue : ('a, 'wls) work_queue
; res_writer : 'a res_queue
}
type ('a, 'wls) t = { work_queue : ('a, 'wls) work_queue }

let init_scheduler () =
let work_queue = Wq.init () in
let res_writer = Wq.init () in
{ work_queue; res_writer }
{ work_queue }

let add_init_task sched task = Wq.push task sched.work_queue

let rec work wls sched =
let rec work wls sched callback =
let rec handle_status (t : _ Schedulable.status) sched =
match t with
| Stop -> ()
| Now x -> Wq.push x sched.res_writer
| Now x -> callback x
| Yield (_prio, f) -> Wq.push f sched.work_queue
| Choice (m1, m2) ->
handle_status m1 sched;
Expand All @@ -156,17 +157,17 @@ end = struct
| Some f -> begin
handle_status (Schedulable.run f wls) sched;
Wq.end_pledge sched.work_queue;
work wls sched
work wls sched callback
end

let spawn_worker sched wls_init =
Wq.make_pledge sched.res_writer;
let spawn_worker sched wls_init callback callback_init callback_close =
callback_init ();
Domain.spawn (fun () ->
let wls = wls_init () in
Fun.protect
~finally:(fun () -> Wq.end_pledge sched.res_writer)
~finally:(fun () -> callback_close ())
(fun () ->
try work wls sched
try work wls sched callback
with e ->
let bt = Printexc.get_raw_backtrace () in
Wq.fail sched.work_queue;
Expand Down Expand Up @@ -295,17 +296,15 @@ end = struct

type 'a run_result = ('a eval * Thread.t) Seq.t

let run ~workers t thread =
let run ~workers t thread ~callback ~callback_init ~callback_end =
let open Scheduler in
let sched = init_scheduler () in
add_init_task sched (State.run t thread);
let join_handles =
Array.map
(fun () -> spawn_worker sched Solver.fresh)
(Array.init workers (Fun.const ()))
Array.init workers (fun _i ->
spawn_worker sched Solver.fresh callback callback_init callback_end )
in
Wq.read_as_seq sched.res_writer ~finalizer:(fun () ->
Array.iter Domain.join join_handles )
join_handles

let trap t =
let* thread in
Expand Down Expand Up @@ -367,7 +366,7 @@ let get_model_or_stop symbol =
| Some v -> return v
end

let select (cond : Symbolic_value.vbool) =
let select_inner ~explore_first (cond : Symbolic_value.vbool) =
let v = Smtml.Expr.simplify cond in
match Smtml.Expr.view v with
| Val True -> return true
Expand All @@ -386,7 +385,11 @@ let select (cond : Symbolic_value.vbool) =
let+ () = check_reachability in
false
in
choose true_branch false_branch
if explore_first then choose true_branch false_branch
else choose false_branch true_branch
[@@inline]

let select (cond : Symbolic_value.vbool) = select_inner cond ~explore_first:true
[@@inline]

let summary_symbol (e : Smtml.Expr.t) =
Expand Down Expand Up @@ -441,7 +444,7 @@ let select_i32 (i : Symbolic_value.int32) =
generator ()

let assertion c =
let* assertion_true = select c in
let* assertion_true = select_inner c ~explore_first:false in
if assertion_true then return ()
else
let* thread in
Expand Down
9 changes: 8 additions & 1 deletion src/symbolic/symbolic_choice.mli
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@ include
and type 'a run_result = ('a eval * Thread.t) Seq.t
and module V := Symbolic_value

val run : workers:int -> 'a t -> Thread.t -> 'a run_result
val run :
workers:int
-> 'a t
-> Thread.t
-> callback:('a eval * Thread.t -> unit)
-> callback_init:(unit -> unit)
-> callback_end:(unit -> unit)
-> unit Domain.t array
5 changes: 3 additions & 2 deletions src/text_to_binary/rewrite.ml
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ let rewrite_const_expr (modul : Assigned.t) (expr : text expr) :
match mut with
| Const -> ok @@ Global_get (Raw idx)
| Var -> Error `Constant_expression_required
end
end
| Ref_null v ->
let+ v = Binary_types.convert_heap_type None v in
Ref_null v
Expand All @@ -364,7 +364,8 @@ let rewrite_const_expr (modul : Assigned.t) (expr : text expr) :
| Array_new_default t ->
let+ t = find "unknown type" modul.typ (Some t) in
Array_new_default t
| (I32_const _ | I64_const _ | F32_const _ | F64_const _ | Ref_i31) | I_binop (_, (Add | Sub | Mul)) as i ->
| ( I32_const _ | I64_const _ | F32_const _ | F64_const _ | Ref_i31
| I_binop (_, (Add | Sub | Mul)) ) as i ->
Ok i
| _i -> Error `Constant_expression_required
in
Expand Down
Loading