Skip to content

Commit

Permalink
cost model uses compute_unit to replace microsecond as cost unit
Browse files Browse the repository at this point in the history
  • Loading branch information
tao-stones committed Sep 30, 2021
1 parent c59a70a commit d244999
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 21 deletions.
21 changes: 14 additions & 7 deletions core/src/cost_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,26 @@ use log::*;
use solana_sdk::{pubkey::Pubkey, transaction::Transaction};
use std::collections::HashMap;

// Guestimated from mainnet-beta data, sigver averages 1us, average read 7us and average write 25us
// 07-27-2021, compute_unit to microsecond conversion ratio collected from mainnet-beta
// differs between instructions. Some bpf instruction has much higher CU/US ratio
// (eg 7vxeyaXGLqcp66fFShqUdHxdacp4k4kwUpRSSeoZLCZ4 has average ratio 135), others
// have lower ratio (eg 9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin has an average ratio 14).
// With this, I am guestimating the flat_fee for sigver and account read/write
// as following. This can be adjusted when needed.
const SIGVER_COST: u64 = 1;
const NON_SIGNED_READONLY_ACCOUNT_ACCESS_COST: u64 = 7;
const NON_SIGNED_WRITABLE_ACCOUNT_ACCESS_COST: u64 = 25;
const NON_SIGNED_READONLY_ACCOUNT_ACCESS_COST: u64 = 1;
const NON_SIGNED_WRITABLE_ACCOUNT_ACCESS_COST: u64 = 2;
const SIGNED_READONLY_ACCOUNT_ACCESS_COST: u64 =
SIGVER_COST + NON_SIGNED_READONLY_ACCOUNT_ACCESS_COST;
const SIGNED_WRITABLE_ACCOUNT_ACCESS_COST: u64 =
SIGVER_COST + NON_SIGNED_WRITABLE_ACCOUNT_ACCESS_COST;

// Sampled from mainnet-beta, the instruction execution timings stats are (in us):
// min=194, max=62164, avg=8214.49, med=2243
pub const ACCOUNT_MAX_COST: u64 = 100_000_000;
pub const BLOCK_MAX_COST: u64 = 2_500_000_000;
// 07-27-2021, cost model limit is set to "worst case scenario", which is the
// max compute unit it can execute. From mainnet-beta, the max CU of instruction
// is 3753, round up to 4_000. Say we allows max 50_000 instruction per writable i
// account, and 1_000_000 instruction per block. It comes to following limits:
pub const ACCOUNT_MAX_COST: u64 = 200_000_000;
pub const BLOCK_MAX_COST: u64 = 4_000_000_000;

const MAX_WRITABLE_ACCOUNTS: usize = 256;

Expand Down
33 changes: 19 additions & 14 deletions core/src/cost_update_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,22 +135,27 @@ impl CostUpdateService {

fn update_cost_model(cost_model: &RwLock<CostModel>, execute_timings: &ExecuteTimings) -> bool {
let mut dirty = false;
let mut cost_model_mutable = cost_model.write().unwrap();
for (program_id, stats) in &execute_timings.details.per_program_timings {
let cost = stats.0 / stats.1 as u64;
match cost_model_mutable.upsert_instruction_cost(program_id, &cost) {
Ok(c) => {
debug!(
"after replayed into bank, instruction {:?} has averaged cost {}",
program_id, c
);
dirty = true;
{
let mut cost_model_mutable = cost_model.write().unwrap();
for (program_id, timing) in &execute_timings.details.per_program_timings {
if timing.count < 1 {
continue;
}
Err(err) => {
debug!(
let units = timing.accumulated_units / timing.count as u64;
match cost_model_mutable.upsert_instruction_cost(program_id, units) {
Ok(c) => {
debug!(
"after replayed into bank, instruction {:?} has averaged cost {}",
program_id, c
);
dirty = true;
}
Err(err) => {
debug!(
"after replayed into bank, instruction {:?} failed to update cost, err: {}",
program_id, err
);
}
}
}
}
Expand Down Expand Up @@ -217,7 +222,7 @@ mod tests {
{
let accumulated_us: u64 = 1000;
let count: u32 = 10;
expected_cost = accumulated_us / count as u64;
expected_cost = accumulated_units / count as u64;

execute_timings
.details
Expand Down Expand Up @@ -247,7 +252,7 @@ mod tests {
let accumulated_us: u64 = 2000;
let count: u32 = 10;
// to expect new cost is Average(new_value, existing_value)
expected_cost = ((accumulated_us / count as u64) + expected_cost) / 2;
expected_cost = ((accumulated_units / count as u64) + expected_cost) / 2;

execute_timings
.details
Expand Down

0 comments on commit d244999

Please sign in to comment.