EIP-2045: Fractional gas costs

According to recent benchmarks, EVM opcodes for computation (ADD, SUB, MUL, etc.) are generally overpriced relative to opcodes for storage I/O (SLOAD, SSTORE, etc.). Currently the minimum gas cost is 1 (i.e. one unit of gas), and most computational opcodes have a cost near to 1 (e.g. 3, 5, or 8), so the range in possible cost reduction is limited. A new minimum unit of gas, called a “particle”, which is a fraction of 1 gas, would expand the range of gas costs and thus enable reductions below the current minimum.

I think instead of lowering the gas cost for simple math the solution is to raise the gas price on storage I/O.

Also, why not milli-gas or micro-gas? (Just not mibi-gas and mibo-gas, please)

From your specification it looks like only a gas unit is added to the gasUsed iff particlesUsed exceeds PARTICLES_PER_GAS.

Does this theoretically mean that if I set a gasLimit of 10000 this means that my actual gasLimit is actually 10000.9999999…9999? (This at least looks to be the case from the spec for the first time the gasUsed increases, via quote: “If particlesUsed exceeds 1 gas, then 1 gas is added to gasUsed (and deducted from particlesUsed ).”)

If yes, I’m not sure if this is correct. I would assume that particlesUsed would invoke a ceil function, not a floor function, to calculate the gas costs. So if particlesUsed either exceeds (>) PARTICLES_PER_GAS or it increases from 0 to a nonzero value then one gas unit is added to gasUsed.

I posted this in the Allcoredev channel, I’ll post it here aswell…

Regarding reducing computational opcodes – I think they are (at least close to) ‘cheap enough’.

We have one op which is only execution of a runloop without any operation being performed: JUMPDEST , which costs 1 gas. See the data from both aleth and geth: https://github.com/ethereum/aleth/issues/5615#issuecomment-499142920 . The jumpdest is fifth heaviest on aleth, second on geth (for the first 1M blocks). This means that 1 gas is not quite enough to pay for the loop, which includes

  • checking op validity,
  • stack requirements,
  • gas requirements,
  • lookup/call function etc.

So I agree that there may be room to lower those that

  • Pops two items and pushes one item (dealloc rather than alloc)
  • Has small spread between worst-case and best-case (e.g. MULMOD has large variance, and may require a lot of alloc or lots of loops)

But I don’t see the need to go into fractions, with all the additional complexity that would bring. Convince me otherwise :slight_smile: