Skip to content

Add new gas metering method: mutable global + local gas function - #34

Merged
athei merged 59 commits into
masterfrom
ag-gas-metering
Nov 20, 2022
Merged

athei merged 59 commits into
masterfrom
ag-gas-metering

Conversation

@agryaznov

Copy link
Copy Markdown
Contributor

Solves #11

In addition to method used beforehand (i.e. injection of calls to an imported gas function into metering blocks), this new method now available too, which:

  • Injects an exported mutable global into the module, which tracks the gas left.
  • Injects the local gas function which subtracts the gas spent from the global, and drops unreachable if out of gas.

This new method should make the resulting module more efficient in terms of execution time, as invoking an imported gas host function every metering block adds an overhead. Synchronization between the global and the runtime should be implemented on the execution engine side.

Comment thread src/gas_metering/mod.rs Outdated
Comment thread src/gas_metering/mod.rs Outdated
Comment thread src/gas_metering/mod.rs Outdated
@agryaznov
agryaznov requested a review from athei October 11, 2022 12:00
@agryaznov

Copy link
Copy Markdown
Contributor Author

new benches is WIP (coming soon)

@agryaznov agryaznov changed the title Add improved gas metering method: mutable global instead of imported gas function Add the improved gas metering method: mutable global instead of imported gas function Oct 11, 2022
Comment thread src/gas_metering/backend.rs Outdated

@athei athei left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do not perform more work in the gas function as necessary.

Comment thread src/gas_metering/mod.rs Outdated
@agryaznov

agryaznov commented Nov 17, 2022 •

Copy link
Copy Markdown
Contributor Author

With new wasmi 0.20 engine, the overheads of calling an imported function and a local function are roughly the same. So the performance wins of using the new gas metering method are in question, and should be sanity-checked for each particular execution engine. Benchmarks are added showing how this could be measured. Versus using an emulated host function they show up to 46% performance decrease for modules instrumented with the new gas metering method. However, these numbers should not be treated as the ultimate truth, as in a real world setup it deeply depends on the host function implementation and where the execution engine resides. Client-side execution engine is expected to have slower host functions, so that's could be a proper use case for the new gas metering method with a mutable global.

This problem:

Just figured out that applying current implementation of stack_limiter injector after gas_metering::mutable_global injector bloats the resulting module massively. The reason is that with current impl of stack_limiter its wraps every call to the local gas function with its stack cost metering instructions. For many_blocks.wasm the overhead is 10x times of original module size.

will be addressed in a follow-up PR.

@agryaznov
agryaznov requested a review from athei November 17, 2022 10:08
@agryaznov agryaznov changed the title Add the improved gas metering method: mutable global instead of imported gas function Add new gas metering method: mutable global + local gas function Nov 17, 2022
@agryaznov

Copy link
Copy Markdown
Contributor Author

Benches

version tested: 6f43fbc

with rustc 1.65, wasmi 0.20.0

fixture host func mut global perf
coremark 20.81 s 20.20 s +3%
recursive_ok 367 µs 585 µs -37%
fibonacci_recursive 9.15 µs 13.56 µs -33%
factorial_recursive 1.50 µs 1.98 µs -24%
count_until 5.03 ms 8.13 ms -38%
memory_vec_add 6.21 ms 8.45 ms -27%
tiny_keccak 925 µs 1080 µs -14%
global_bump 3.79 ms 7.03 ms -46%

Comment thread src/gas_metering/mod.rs Outdated
Comment thread src/gas_metering/mod.rs Outdated
Comment thread src/gas_metering/mod.rs Outdated
Comment thread src/gas_metering/mod.rs Outdated
Comment thread src/gas_metering/mod.rs Outdated
Comment thread tests/diff.rs Outdated
@agryaznov
agryaznov force-pushed the ag-gas-metering branch 2 times, most recently from db2d4e5 to 5084aa4 Compare November 18, 2022 19:44
@athei
athei merged commit a4dde28 into master Nov 20, 2022
@athei
athei deleted the ag-gas-metering branch November 20, 2022 14:00
ukint-vs pushed a commit to gear-tech/wasm-instrument that referenced this pull request Oct 3, 2024
…aritytech#34)

* fix misprints in doc comments

* added global gas tracker variable and local gas fn

* all exported functions of the module to accept a new param and to set the gas_left global to its value at their very start

* make module support both gas metering methods

* tests fixed for the old metering method

* better naming

* MutableGlobal metering method implemented, tests for the old method pass

* gas_metering::tests updated and pass

* all tests udpdated and pass

* emacs backup files to .gitignore

* docs updated

* clippy fix

* iff = if and only if

* more clippy

* docs misprints fixes

* refactored to have Backend trait and two implementations in separate sub-modules

* docs updated

* fixed old benches (updating them is coming next)

* added bench for an instrumented wasm-coremark

* updated benches: added them for both gas_metering instrumentations

* benches contest first ver

* added debug prints to the bench

* refactored to better fit frontend-backend pattern

* docs update

* updated benches

* design updated on feedback

* re-structured sub-modules

re-structured sub-modules & updated docs

* docs improved

* addressed latest feedback comments

* re-writed the local gas function

* coremark benches show ~20% performance improvement

* fix ci: test + clippy

* save before re-factoring prepare_in_wasm()

* bare_call_16 shows 16% worse perf

* + fibonacci recursive bench

* refactored benchmarks

* + factorial recursive bench

* benches on wasmi fixtures show no perf improvement, coremark runs ~20% faster being instrumented with mutable_global gas metering

* charge gas for local gas func isntructions execution

* replaced benchmark which requires multi_value feature

* save: optimized gas func a bit (benches work, fixture tests fail)

* 1033% overhead on many_blocks.wasm when mut_global gas_metering together with stack_height

* size overhead test for both gas metering methods + stack limiter

* added more benches

* improved print_size_overhead test

* test for comparing size overheads of two gas_metering injectors

* before optimization: benches + size overhead

* optimization try-1: inline part of gas func instructions: +benches +size overheads

* optimization try-2: inline hot path of gas fn:  +benches +size overheads

* opt try-3: count for gas fn cost on the caller side: +benches +size overhead

* revert to initial version but with static gas fn cost on the caller side: +benches +sizes

* tests fixed

* use newest wasmi 0.20: +benches +docs updated

* use if-else block instead of Return: +benches

* fix tests

* clippy fix

* addressed review comments

* Update changelog

Co-authored-by: Alexander Theißen <alex.theissen@me.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants