diff --git a/src/bin_snoop/snoop-command.t b/src/bin_snoop/snoop-command.t index be8a3673c46dde2f17bc1db12726272159e29a5e..66833d726f215cecfa062babfbf4d26c5390072e 100644 --- a/src/bin_snoop/snoop-command.t +++ b/src/bin_snoop/snoop-command.t @@ -1,6 +1,7 @@ Missing config file prints $ ./main_snoop.exe benchmark N_IBlake2b_alpha and save to output.json -c __nosuchdir --bench-num 1 2>&1 | sed s'/stats over all benchmarks:.*/stats /' Model N_IOpt_map_alpha already registered for code generation! (overloaded instruction?) Ignoring. + Model N_ILambda_alpha already registered for code generation! (overloaded instruction?) Ignoring. Model N_ISapling_verify_update_alpha already registered for code generation! (overloaded instruction?) Ignoring. Model N_ISapling_verify_update_alpha already registered for code generation! (overloaded instruction?) Ignoring. Model N_ISapling_verify_update_alpha already registered for code generation! (overloaded instruction?) Ignoring. diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml index 6748de72b07518fc45a894bbffc38dd0398b53d0..cb9c98c540df0eb7f73c167d3b22a6ffae982d06 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_benchmarks.ml @@ -2018,9 +2018,28 @@ module Registration_section = struct let dummy_lambda = let open Script_typed_ir in let descr = - {kloc = 0; kbef = unit @$ bot; kaft = unit @$ bot; kinstr = halt} + { + kloc = dummy_loc; + kbef = unit @$ bot; + kaft = unit @$ bot; + kinstr = halt; + } + in + Lam (descr, Micheline.Int (dummy_loc, Z.zero)) + + let dummy_lambda_rec = + let open Script_typed_ir in + let descr = + { + kloc = dummy_loc; + kbef = unit @$ lambda unit unit @$ bot; + kaft = unit @$ bot; + kinstr = + IDrop + (dummy_loc, IDrop (dummy_loc, IConst (dummy_loc, unit, (), halt))); + } in - Lam (descr, Micheline.Int (0, Z.zero)) + LamRec (descr, Micheline.Int (dummy_loc, Z.zero)) let () = (* @@ -2033,7 +2052,9 @@ module Registration_section = struct ~name:Interpreter_workload.N_IExec ~stack_type:(unit @$ lambda unit unit @$ bot) ~kinstr:(IExec (dummy_loc, Some (unit @$ bot), halt)) - ~stack_sampler:(fun _cfg _rng_state () -> ((), (dummy_lambda, eos))) + ~stack_sampler:(fun _cfg rng_state () -> + if Base_samplers.uniform_bool rng_state then ((), (dummy_lambda, eos)) + else ((), (dummy_lambda_rec, eos))) () let () = @@ -2044,23 +2065,41 @@ module Registration_section = struct construct term -> IHalt *) - let code = + let dummy_lambda_pair = let open Script_typed_ir in let descr = { - kloc = 0; + kloc = dummy_loc; kbef = cpair unit unit @$ bot; kaft = unit @$ bot; kinstr = ICdr (dummy_loc, halt); } in - Lam (descr, Micheline.Int (0, Z.zero)) + Lam (descr, Micheline.Int (dummy_loc, Z.zero)) + in + let dummy_lambda_pair_rec = + let open Script_typed_ir in + let descr = + { + kloc = dummy_loc; + kbef = cpair unit unit @$ lambda (cpair unit unit) unit @$ bot; + kaft = unit @$ bot; + kinstr = + IDrop + ( dummy_loc, + IDrop (dummy_loc, IConst (dummy_loc, unit, (), halt)) ); + } + in + LamRec (descr, Micheline.Int (dummy_loc, Z.zero)) in simple_benchmark_with_stack_sampler ~name:Interpreter_workload.N_IApply ~stack_type:(unit @$ lambda (cpair unit unit) unit @$ bot) ~kinstr:(IApply (dummy_loc, unit, halt)) - ~stack_sampler:(fun _cfg _rng_state () -> ((), (code, eos))) + ~stack_sampler:(fun _cfg rng_state () -> + if Base_samplers.uniform_bool rng_state then + ((), (dummy_lambda_pair, eos)) + else ((), (dummy_lambda_pair_rec, eos))) () let () = @@ -2074,6 +2113,18 @@ module Registration_section = struct ~kinstr:(ILambda (dummy_loc, dummy_lambda, halt)) () + let () = + (* + ILambda (rec) -> + IHalt + *) + simple_benchmark + ~name:Interpreter_workload.N_ILambda + ~salt:"_rec" + ~stack_type:(unit @$ bot) + ~kinstr:(ILambda (dummy_loc, dummy_lambda_rec, halt)) + () + let () = (* IFailwith -> diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml index 10224dc78f35eba7d437ad41e3d6cf2de12c5bdb..bfeb4cc4e774e8a58ecb328d10069e8f01a55014 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_model.ml @@ -309,7 +309,7 @@ module Models = struct end in (module M : Model.Model_impl with type arg_type = int * (int * unit)) - let branching_model name = + let branching_model ~case_0 ~case_1 name = let module M = struct type arg_type = int * unit @@ -324,12 +324,17 @@ module Models = struct lam ~name:"size" @@ fun size -> if_ (eq size (int 0)) - (free ~name:(fv (sf "%s_empty" name))) - (free ~name:(fv (sf "%s_nonempty" name))) + (free ~name:(fv (sf "%s_%s" name case_0))) + (free ~name:(fv (sf "%s_%s" name case_1))) end end in (module M : Model.Model_impl with type arg_type = int * unit) + let empty_branch_model name = + branching_model ~case_0:"empty" ~case_1:"nonempty" name + + let apply_model name = branching_model ~case_0:"lam" ~case_1:"lamrec" name + let join_tickets_model name = let module M = struct type arg_type = int * (int * (int * (int * unit))) @@ -452,7 +457,7 @@ let ir_model ?specialization instr_or_cont = | N_IMap_iter -> model_1 instr_or_cont (affine_model name) | N_ISet_iter -> model_1 instr_or_cont (affine_model name) | N_IHalt -> model_0 instr_or_cont (const1_model name) - | N_IApply -> model_0 instr_or_cont (const1_model name) + | N_IApply -> model_1 instr_or_cont (apply_model name) | N_ILog -> model_0 instr_or_cont (const1_model name) | N_IOpen_chest -> model_2 instr_or_cont (open_chest_model name) | N_IEmit -> model_0 instr_or_cont (const1_model name)) @@ -466,10 +471,10 @@ let ir_model ?specialization instr_or_cont = | N_KUndip -> model_0 instr_or_cont (const1_model name) | N_KLoop_in -> model_0 instr_or_cont (const1_model name) | N_KLoop_in_left -> model_0 instr_or_cont (const1_model name) - | N_KIter -> model_1 instr_or_cont (branching_model name) + | N_KIter -> model_1 instr_or_cont (empty_branch_model name) | N_KList_enter_body -> model_2 instr_or_cont (list_enter_body_model name) | N_KList_exit_body -> model_0 instr_or_cont (const1_model name) - | N_KMap_enter_body -> model_1 instr_or_cont (branching_model name) + | N_KMap_enter_body -> model_1 instr_or_cont (empty_branch_model name) | N_KMap_exit_body -> model_2 instr_or_cont (nlogm_model name) | N_KLog -> model_0 instr_or_cont (const1_model name)) diff --git a/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml b/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml index ad3a114d248fa755520f129f6095a00cc253dfeb..17146ea2f3052ba84b70f6b3ce3f41c6902e5a68 100644 --- a/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml +++ b/src/proto_alpha/lib_benchmarks_proto/interpreter_workload.ml @@ -915,7 +915,8 @@ module Instructions = struct let exec = ir_sized_step N_IExec nullary - let apply = ir_sized_step N_IApply nullary + let apply ~(rec_flag : bool) = + ir_sized_step N_IApply (unary "rec" (if rec_flag then 1 else 0)) let lambda = ir_sized_step N_ILambda nullary @@ -1314,7 +1315,10 @@ let extract_ir_sized_step : | ILoop_left (_, _, _), _ -> Instructions.loop_left | IDip (_, _, _, _), _ -> Instructions.dip | IExec (_, _, _), _ -> Instructions.exec - | IApply (_, _, _), _ -> Instructions.apply + | IApply (_, _, _), (_, (l, _)) -> ( + match l with + | Lam _ -> Instructions.apply ~rec_flag:false + | LamRec _ -> Instructions.apply ~rec_flag:true) | ILambda (_, _, _), _ -> Instructions.lambda | IFailwith (_, _), _ -> Instructions.failwith_ | ICompare (_, cmp_ty, _), (a, (b, _)) -> diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml index 4111d92bb21dc68ddb7d20347ef44302d1c45153..6a578209dceafe01fc87409d15ed1b2ef8b046f4 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml @@ -121,7 +121,8 @@ module Cost_of = struct S.safe_int 35 + ((v0 lsr 4) + (v0 lsr 7)) (* model N_IApply *) - let cost_N_IApply = S.safe_int 140 + let cost_N_IApply rec_flag = + if rec_flag then S.safe_int 220 else S.safe_int 140 (* model N_IBlake2b *) (* Approximating 1.120804 x term *) @@ -1272,7 +1273,7 @@ module Cost_of = struct let exec = atomic_step_cost cost_N_IExec - let apply = atomic_step_cost cost_N_IApply + let apply ~(rec_flag : bool) = atomic_step_cost (cost_N_IApply rec_flag) let lambda = atomic_step_cost cost_N_ILambda diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli index b91b3cd478386a857aced7aa37f620b5b143c024..f799d7d556400ed447e3c5ba910ced14b57a436a 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli @@ -291,7 +291,7 @@ module Cost_of : sig val exec : Gas.cost - val apply : Gas.cost + val apply : rec_flag:bool -> Gas.cost val lambda : Gas.cost diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index b483dc0d62d6ac9f1427012a8febe9d7ccb2e218..ca1c4d82f92fc7ec3287734665be6f4a29385635 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -288,7 +288,11 @@ let cost_of_instr : type a s r f. (a, s, r, f) kinstr -> a -> s -> Gas.cost = | ILoop_left _ -> Interp_costs.loop_left | IDip _ -> Interp_costs.dip | IExec _ -> Interp_costs.exec - | IApply _ -> Interp_costs.apply + | IApply _ -> ( + let l, _ = stack in + match l with + | Lam _ -> Interp_costs.apply ~rec_flag:false + | LamRec _ -> Interp_costs.apply ~rec_flag:true) | ILambda _ -> Interp_costs.lambda | IFailwith _ -> Gas.free | IEq _ -> Interp_costs.eq diff --git a/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_costs.ml b/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_costs.ml index ab5546d1fe6bc5e47677f8f98816d32000279f62..c7c7f2ed772953dddb8c0a5905db0168d3ca7bd8 100644 --- a/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_costs.ml +++ b/src/proto_alpha/lib_protocol/test/integration/gas/test_gas_costs.ml @@ -154,7 +154,8 @@ let all_interpreter_costs = ("concat_string", concat_string (S.safe_int 42)); ("concat_bytes", concat_bytes (S.safe_int 42)); ("exec", exec); - ("apply", apply); + ("apply_rec", apply ~rec_flag:true); + ("apply", apply ~rec_flag:false); ("lambda", lambda); ("address", address); ("contract", contract);