Improve instruction benchmarks (#9712)

* seal_input can be called multiple times

* Increase size of instruction benchmarks

* Remove randomness from instr_br* benchmarks

* cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_contracts --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/contracts/src/weights.rs --template=./.maintain/frame-weight-template.hbs

Co-authored-by: Parity Bot <admin@parity.io>
This commit is contained in:
Alexander Theißen
2021-09-09 11:12:08 +02:00
committed by GitHub
parent 5666d9de94
commit a443944167
5 changed files with 608 additions and 606 deletions
+2 -2
View File
@@ -6540,9 +6540,9 @@ dependencies = [
[[package]]
name = "pwasm-utils"
version = "0.18.1"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c1a2f10b47d446372a4f397c58b329aaea72b2daf9395a623a411cb8ccb54f"
checksum = "880b3384fb00b8f6ecccd5d358b93bd2201900ae3daad213791d1864f6441f5c"
dependencies = [
"byteorder",
"log 0.4.14",
+1 -1
View File
@@ -19,7 +19,7 @@ codec = { package = "parity-scale-codec", version = "2.2.0", default-features =
"max-encoded-len",
] }
log = { version = "0.4", default-features = false }
pwasm-utils = { version = "0.18", default-features = false }
pwasm-utils = { version = "0.18.2", default-features = false }
serde = { version = "1", optional = true, features = ["derive"] }
smallvec = { version = "1", default-features = false, features = [
"const_generics",
@@ -50,7 +50,7 @@ use sp_std::{convert::TryInto, default::Default, vec, vec::Vec};
const API_BENCHMARK_BATCHES: u32 = 20;
/// How many batches we do per Instruction benchmark.
const INSTR_BENCHMARK_BATCHES: u32 = 1;
const INSTR_BENCHMARK_BATCHES: u32 = 50;
/// An instantiated and deployed contract.
struct Contract<T: Config> {
@@ -444,11 +444,8 @@ benchmarks! {
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![])
// We cannot call seal_input multiple times. Therefore our weight determination is not
// as precise as with other APIs. Because this function can only be called once per
// contract it cannot be used for Dos.
seal_input {
let r in 0 .. 1;
let r in 0 .. API_BENCHMARK_BATCHES;
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
@@ -463,7 +460,7 @@ benchmarks! {
value: 0u32.to_le_bytes().to_vec(),
},
],
call_body: Some(body::repeated(r, &[
call_body: Some(body::repeated(r * API_BENCHMARK_BATCH_SIZE, &[
Instruction::I32Const(4), // ptr where to store output
Instruction::I32Const(0), // ptr to length
Instruction::Call(0),
@@ -492,11 +489,10 @@ benchmarks! {
value: buffer_size.to_le_bytes().to_vec(),
},
],
call_body: Some(body::plain(vec![
call_body: Some(body::repeated(API_BENCHMARK_BATCH_SIZE, &[
Instruction::I32Const(4), // ptr where to store output
Instruction::I32Const(0), // ptr to length
Instruction::Call(0),
Instruction::End,
])),
.. Default::default()
});
@@ -505,7 +501,9 @@ benchmarks! {
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), data)
// The same argument as for `seal_input` is true here.
// We cannot call `seal_return` multiple times. Therefore our weight determination is not
// as precise as with other APIs. Because this function can only be called once per
// contract it cannot be used as an attack vector.
seal_return {
let r in 0 .. 1;
let code = WasmModule::<T>::from(ModuleDefinition {
@@ -551,7 +549,7 @@ benchmarks! {
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![])
// The same argument as for `seal_input` is true here.
// The same argument as for `seal_return` is true here.
seal_terminate {
let r in 0 .. 1;
let beneficiary = account::<T::AccountId>("beneficiary", 0, 0);
@@ -1509,6 +1507,7 @@ benchmarks! {
}
// w_br = w_bench - 2 * w_param
// Block instructions are not counted.
instr_br {
let r in 0 .. INSTR_BENCHMARK_BATCHES;
let mut sbox = Sandbox::from(&WasmModule::<T>::from(ModuleDefinition {
@@ -1533,9 +1532,8 @@ benchmarks! {
sbox.invoke();
}
// w_br_if = w_bench - 5 * w_param
// The two additional pushes + drop are only executed 50% of the time.
// Making it: 3 * w_param + (50% * 4 * w_param)
// w_br_if = w_bench - 3 * w_param
// Block instructions are not counted.
instr_br_if {
let r in 0 .. INSTR_BENCHMARK_BATCHES;
let mut sbox = Sandbox::from(&WasmModule::<T>::from(ModuleDefinition {
@@ -1543,7 +1541,7 @@ benchmarks! {
Regular(Instruction::Block(BlockType::NoResult)),
Regular(Instruction::Block(BlockType::NoResult)),
Regular(Instruction::Block(BlockType::NoResult)),
RandomI32(0, 2),
Regular(Instruction::I32Const(1)),
Regular(Instruction::BrIf(1)),
RandomI64Repeated(1),
Regular(Instruction::Drop),
@@ -1562,11 +1560,11 @@ benchmarks! {
}
// w_br_table = w_bench - 3 * w_param
// 1 * w_param + 0.5 * 2 * w_param + 0.25 * 4 * w_param
// Block instructions are not counted.
instr_br_table {
let r in 0 .. INSTR_BENCHMARK_BATCHES;
let table = Box::new(BrTableData {
table: Box::new([0, 1, 2]),
table: Box::new([1, 1, 1]),
default: 1,
});
let mut sbox = Sandbox::from(&WasmModule::<T>::from(ModuleDefinition {
+4 -4
View File
@@ -36,7 +36,7 @@ pub const API_BENCHMARK_BATCH_SIZE: u32 = 100;
/// How many instructions are executed in a single batch. The reasoning is the same
/// as for `API_BENCHMARK_BATCH_SIZE`.
pub const INSTR_BENCHMARK_BATCH_SIZE: u32 = 1_000;
pub const INSTR_BENCHMARK_BATCH_SIZE: u32 = 100;
/// Definition of the cost schedule and other parameterizations for the wasm vm.
///
@@ -495,7 +495,7 @@ impl<T: Config> Default for InstructionWeights<T> {
select: cost_instr!(instr_select, 4),
r#if: cost_instr!(instr_if, 3),
br: cost_instr!(instr_br, 2),
br_if: cost_instr!(instr_br_if, 5),
br_if: cost_instr!(instr_br_if, 3),
br_table: cost_instr!(instr_br_table, 3),
br_table_per_entry: cost_instr!(instr_br_table_per_entry, 0),
call: cost_instr!(instr_call, 2),
@@ -559,8 +559,8 @@ impl<T: Config> Default for HostFnWeights<T> {
now: cost_batched!(seal_now),
weight_to_fee: cost_batched!(seal_weight_to_fee),
gas: cost_batched!(seal_gas),
input: cost!(seal_input),
input_per_byte: cost_byte!(seal_input_per_kb),
input: cost_batched!(seal_input),
input_per_byte: cost_byte_batched!(seal_input_per_kb),
r#return: cost!(seal_return),
return_per_byte: cost_byte!(seal_return_per_kb),
terminate: cost!(seal_terminate),
File diff suppressed because it is too large Load Diff