Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
evm: add some mulmod benches (#10600)
Browse files Browse the repository at this point in the history
* evm: add blockhash_mulmod bench

* evm: use num-bigint for mod ops
  • Loading branch information
ordian authored and HCastano committed Apr 29, 2019
1 parent 64fd64f commit 4723ea6
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 11 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ethcore/evm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ vm = { path = "../vm" }
keccak-hash = "0.1"
parking_lot = "0.7"
memory-cache = { path = "../../util/memory-cache" }
num-bigint = "0.2"

[dev-dependencies]
rustc-hex = "1.0"
Expand Down
52 changes: 51 additions & 1 deletion ethcore/evm/benches/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ criterion_group!(
mem_gas_calculation_same_usize,
mem_gas_calculation_same_u256,
mem_gas_calculation_increasing_usize,
mem_gas_calculation_increasing_u256
mem_gas_calculation_increasing_u256,
blockhash_mulmod_small,
blockhash_mulmod_large,
);
criterion_main!(basic);

Expand Down Expand Up @@ -150,6 +152,54 @@ fn mem_gas_calculation_increasing(gas: U256, b: &mut Bencher) {
});
}

fn blockhash_mulmod_small(b: &mut Criterion) {
b.bench_function("blockhash_mulmod_small", |b| {
let factory = Factory::default();
let mut ext = FakeExt::new();

let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();

b.iter(|| {
let code = black_box(
"6080604052348015600f57600080fd5b5060005a90505b60c881111560de5760017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8009505a90506016565b506035806100ed6000396000f3fe6080604052600080fdfea165627a7a72305820bde4a0ac6d0fac28fc879244baf8a6a0eda514bc95fb7ecbcaaebf2556e2687c0029".from_hex().unwrap()
);

let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(4_000u64);
params.code = Some(Arc::new(code.clone()));

let vm = factory.create(params, ext.schedule(), 0);

result(vm.exec(&mut ext).ok().unwrap())
});
});
}

fn blockhash_mulmod_large(b: &mut Criterion) {
b.bench_function("blockhash_mulmod_large", |b| {
let factory = Factory::default();
let mut ext = FakeExt::new();

let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();

b.iter(|| {
let code = black_box(
"608060405234801561001057600080fd5b5060005a90505b60c8811115610177577efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009505a9050610017565b506035806101866000396000f3fe6080604052600080fdfea165627a7a72305820dcaec306f67bb96f3044fff25c9af2ec66f01d0954d0656964f046f42f2780670029".from_hex().unwrap()
);

let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(4_000u64);
params.code = Some(Arc::new(code.clone()));

let vm = factory.create(params, ext.schedule(), 0);

result(vm.exec(&mut ext).ok().unwrap())
});
});
}

fn result(r: Result<evm::GasLeft>) -> U256 {
match r {
Ok(GasLeft::Known(gas_left)) => gas_left,
Expand Down
35 changes: 25 additions & 10 deletions ethcore/evm/src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ use std::{cmp, mem};
use std::sync::Arc;
use hash::keccak;
use bytes::Bytes;
use ethereum_types::{U256, U512, H256, Address};
use ethereum_types::{U256, H256, Address};
use num_bigint::BigUint;

use vm::{
self, ActionParams, ParamsType, ActionValue, CallType, MessageCallResult,
Expand Down Expand Up @@ -61,6 +62,17 @@ const TWO_POW_96: U256 = U256([0, 0x100000000, 0, 0]); //0x1 00000000 00000000 0
const TWO_POW_224: U256 = U256([0, 0, 0, 0x100000000]); //0x1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
const TWO_POW_248: U256 = U256([0, 0, 0, 0x100000000000000]); //0x1 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000000

fn to_biguint(x: U256) -> BigUint {
let mut bytes = [0u8; 32];
x.to_little_endian(&mut bytes);
BigUint::from_bytes_le(&bytes)
}

fn from_biguint(x: BigUint) -> U256 {
let bytes = x.to_bytes_le();
U256::from_little_endian(&bytes)
}

/// Abstraction over raw vector of Bytes. Easier state management of PC.
struct CodeReader {
position: ProgramCounter,
Expand Down Expand Up @@ -1009,11 +1021,12 @@ impl<Cost: CostType> Interpreter<Cost> {
let c = self.stack.pop_back();

self.stack.push(if !c.is_zero() {
// upcast to 512
let a5 = U512::from(a);
let res = a5.overflowing_add(U512::from(b)).0;
let x = res % U512::from(c);
U256::from(x)
let a_num = to_biguint(a);
let b_num = to_biguint(b);
let c_num = to_biguint(c);
let res = a_num + b_num;
let x = res % c_num;
from_biguint(x)
} else {
U256::zero()
});
Expand All @@ -1024,10 +1037,12 @@ impl<Cost: CostType> Interpreter<Cost> {
let c = self.stack.pop_back();

self.stack.push(if !c.is_zero() {
let a5 = U512::from(a);
let res = a5.overflowing_mul(U512::from(b)).0;
let x = res % U512::from(c);
U256::from(x)
let a_num = to_biguint(a);
let b_num = to_biguint(b);
let c_num = to_biguint(c);
let res = a_num * b_num;
let x = res % c_num;
from_biguint(x)
} else {
U256::zero()
});
Expand Down
1 change: 1 addition & 0 deletions ethcore/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern crate vm;
extern crate keccak_hash as hash;
extern crate memory_cache;
extern crate parity_bytes as bytes;
extern crate num_bigint;

#[macro_use]
extern crate lazy_static;
Expand Down

0 comments on commit 4723ea6

Please sign in to comment.