Stream: wasmtime

Topic: Fuel to CPU instructions


view this post on Zulip Ashanti Mutinta (Apr 26 2024 at 17:08):

Couldn't find any information about this but I have been using Fuel Yielding to do some async scheduling of sandboxes. I was wondering if there was any information about the correlation of fuel instructions to cpu instructions. E.G sandbox 1 with 2000 fuel and sandbox 2 with the same fuel, Would they relatively use same amount of cpu cycles?

view this post on Zulip fitzgen (he/him) (Apr 26 2024 at 17:10):

there is a more direct relationship between fuel and wasm instructions, where each wasm instruction takes about 1 unit of fuel, although there are some that take zero (eg end)

as cranelift is an optimizing compiler, we can't give any precise relationship between wasm instructions and machine instructions, as it depends on the particular wasm instructions in the function as well as how much potential there is for things like deduplicating repeatedly computed subexpressions

view this post on Zulip fitzgen (he/him) (Apr 26 2024 at 17:12):

the Store::set_fuel docs say it better than me:

Most WebAssembly instructions consume 1 unit of fuel. Some instructions, such as nop, drop, block, and loop, consume 0 units, as any execution cost associated with them involves other instructions which do consume fuel.

view this post on Zulip fitzgen (he/him) (Apr 26 2024 at 17:12):

https://docs.rs/wasmtime/latest/wasmtime/struct.Store.html#method.set_fuel

view this post on Zulip Ashanti Mutinta (Apr 26 2024 at 17:15):

This is perfect thank you very much

view this post on Zulip fitzgen (he/him) (Apr 26 2024 at 17:18):

E.G sandbox 1 with 2000 fuel and sandbox 2 with the same fuel, Would they relatively use same amount of cpu cycles?

in general, for real world programs, yes they will use roughly the same amount of cycles.

but you could certainly craft a pair of programs where program A can be const-folded down to returning a single constant value by cranelift and therefore uses just a handful of cycles to run and returns before hitting the fuel limit, and program B doesn't have any code that cranelift can optimize and will run out fuel before returning. and both programs could be made up of the same number of wasm instructions.

if you want to side step this kind of thing, you can use winch, instead of cranelift, which is a non-optimizing baseline-style compiler, and it will emit a canned sequence of machine instructions for each wasm instruction it sees

view this post on Zulip Ashanti Mutinta (Apr 26 2024 at 17:27):

Awesome thank you this has been very informative

view this post on Zulip Chris Fallin (Apr 26 2024 at 18:07):

One thing to note as well as that instructions != cycles; all the statements above are true wrt instructions (somewhat predictable, not perfectly, moreso with winch) but cycle count can vary dramatically depending on what the program's doing

view this post on Zulip Chris Fallin (Apr 26 2024 at 18:07):

two basic sources of time variance to consider, for example -- cache misses, branch mispredictions

view this post on Zulip fitzgen (he/him) (Apr 26 2024 at 18:08):

ah yes, good point

view this post on Zulip Chris Fallin (Apr 26 2024 at 18:08):

so in theory two programs consuming N fuel and running K CPU instructions each could take 10x-100x different cycle counts if e.g. a parameter controlled a stride length in a memory-accessing loop and pushed it beyond cache/prefetchers

view this post on Zulip Chris Fallin (Apr 26 2024 at 18:09):

@Ashanti Mutinta if you're looking to closely monitor or control instructions or cycles or both, most CPUs today have "hardware performance counters" that can do this; Wasmtime doesn't have any integration with this at the moment though

view this post on Zulip Ashanti Mutinta (Apr 26 2024 at 18:20):

Awesome thank you! This is really helpful. I'm looking into using fuel_yield to check cpu usage. Aftet each fuel yield in the future i wrote I'm checking how much cpu was used in the 'pending' branch but I had a thought that what I might be a bit redundant if the cpu cycles are the same with the same fuel set

view this post on Zulip Chris Fallin (Apr 26 2024 at 18:21):

using fuel interrupts to query perf counters would make sense. I might also look into using epoch interruption for that: since the interrupt frequency is not critical to be precise if you're just time-integrating perf counters, epochs have lower overhead

view this post on Zulip Ashanti Mutinta (Apr 26 2024 at 18:22):

Thank you. I love epoch counters, but I need to also set high cpu boxes to idle so the pending branch is a good way to 'sleep' the sandbox

view this post on Zulip Ashanti Mutinta (Apr 26 2024 at 18:30):

This has been really great thank you all


Last updated: Dec 23 2024 at 13:07 UTC