## Gas update 005

This MR amends the gas cost to match that of the fitted cost model (see currently freshest branch [email protected]_bench).

The modifications are structured as follows:

- Allow finer-grained step cost accounting. This is the most invasive part, as we need to introduce new interpreter-specific accounting functions with some non-trivial invariants to be respected (a cleaner alternative would be to rescale all gas costs as well a per-op/per-block limits by eg 2^7).
- Decouple cost functions used in the interpreter from that used elsewhere, ensuring that gas costs of non-benchmarked parts of the protocol are not altered.
- Replace old gas costs with new ones.

In details: Our measures only consider execution time and the cost model predicts execution time only (not memory). Hence, we must map cost functions expressed in nanoseconds to cost functions expressed in symbolic, vectorial costs (Gas_limit_repr.cost) and indirectly in gas (via Gas_limit_repr.consume). In order for this conversion to be performed, some "meta parameters" have to be fixed, some of which are not part of the protocol (but maybe should): max gas per block and max validation time per block. We fixed the latter to 5 seconds.

Some consequences :

- All new cost functions do not record directly allocation costs. Allocation costs are only measured indirectly insofar we measure allocation time and GC time. We believe it is not currently possible to blow up the memory without blowing up execution time (in particular because logical shifts are bounded) but feedback on this matter is required.
- With the aforementioned meta parameters, it appears that the granularity of one unit of gas is roughly of 630ns. This is not fine enough to express our cost models. We thus introduced "atomic_step_cost" in Gas_limit_repr as well as "incr_interpreter_cost" and "bill_interpeter_cost" in Raw_context/Alpha_context. The ratio between "step_cost" and "atomic_step_cost" is fixed in Gas_limit_repr to 128 (a power of two for arithmetic convenience).
- The abstract cost model works with real values. The protocol works with integers. In order to minimize bugs, the new cost functions were metaprogrammed, including a scheme to map float x int multiplies to (heuristically and statically decided) either fixed precision computations or integer multiplications/divisions.

How to understand `Michelson_v1_gas.Cost_of.Interpreter`

- For each instructions (eg
`ADD`

), we have a cost model that predicts the execution time as a function of the size (in bytes) of the arguments. For`ADD`

, it looks like`\alpha_0 + \alpha_1 * max(size1,size2)`

.`\alpha_0`

and`alpha_1`

are parameters that are fitted by measuring the execution time of`Script_interpreter.step`

on arguments of various sizes. - Once the parameters are fitted, this cost function has to be mapped to cost functions as defined in
`Michelson_v1_gas.Cost_of`

. In the case of`ADD`

, we see that we pay`Michelson_v1_gas.Cost_of.step`

and`Michelson_v1_gas.Cost_of.add_sub_z x y`

where`x`

and`y`

are the integers being added. These functions are labelled in gas, not in seconds, so we have to map the fitted model from seconds into gas and then split it into a`step`

part and a`add_sub_z`

part. - A last issue is that the fitted parameters are represented as floating point numbers while the protocol only deals with integers. So we have to map these to fixed-precision computations, or integer divide multiply.

Steps 2 and 3 are done mechanically (including code generation) in a file not part of this patch (but linked below).

See the attached file for the raw benchmark results: report_17_juin.pdf

See here for the code that generated `Michelson_v1_gas.Cost_of.Interpreter`