Add Measure abstraction over measuring time intervals (#4851)

Allows one to swap in different implementations. This provides
the normal Insant::now() -> .elapsed() path.
This commit is contained in:
sakridge
2019-06-29 15:34:49 +02:00
committed by GitHub
parent 41bda18046
commit a89589a1d5
12 changed files with 158 additions and 61 deletions

View File

@ -26,6 +26,7 @@ serde = "1.0.94"
serde_derive = "1.0.94"
serde_json = "1.0.38"
solana-logger = { path = "../logger", version = "0.17.0" }
solana-measure = { path = "../measure", version = "0.17.0" }
solana-metrics = { path = "../metrics", version = "0.17.0" }
solana-bpf-loader-api = { path = "../programs/bpf_loader_api", version = "0.17.0" }
solana-bpf-loader-program = { path = "../programs/bpf_loader_program", version = "0.17.0" }

View File

@ -28,6 +28,7 @@ use rayon::ThreadPool;
use serde::de::{MapAccess, Visitor};
use serde::ser::{SerializeMap, Serializer};
use serde::{Deserialize, Serialize};
use solana_measure::measure::Measure;
use solana_sdk::account::{Account, LamportCredit};
use solana_sdk::pubkey::Pubkey;
use std::collections::{HashMap, HashSet};
@ -530,10 +531,12 @@ impl AccountsDB {
) -> (Vec<(Fork, AccountInfo)>, u64) {
let mut reclaims: Vec<(Fork, AccountInfo)> = Vec::with_capacity(infos.len() * 2);
let mut index = self.accounts_index.write().unwrap();
let mut update_index_work = Measure::start("update_index_work");
for (info, account) in infos.into_iter().zip(accounts.iter()) {
let key = &account.0;
index.insert(fork_id, key, info, &mut reclaims);
}
update_index_work.stop();
(reclaims, index.last_root)
}
@ -582,20 +585,30 @@ impl AccountsDB {
/// Store the account update.
pub fn store(&self, fork_id: Fork, accounts: &HashMap<&Pubkey, &Account>) {
let mut store_accounts = Measure::start("store::store_accounts");
let infos = self.store_accounts(fork_id, accounts);
store_accounts.stop();
let mut update_index = Measure::start("store::update_index");
let (reclaims, last_root) = self.update_index(fork_id, infos, accounts);
update_index.stop();
trace!("reclaim: {}", reclaims.len());
let mut remove_dead_accounts = Measure::start("store::remove_dead");
let mut dead_forks = self.remove_dead_accounts(reclaims);
remove_dead_accounts.stop();
trace!("dead_forks: {}", dead_forks.len());
let mut cleanup_dead_forks = Measure::start("store::cleanup_dead_forks");
self.cleanup_dead_forks(&mut dead_forks, last_root);
cleanup_dead_forks.stop();
trace!("purge_forks: {}", dead_forks.len());
let mut purge_forks = Measure::start("store::purge_forks");
for fork in dead_forks {
self.purge_fork(fork);
}
purge_forks.stop();
}
pub fn add_root(&self, fork: Fork) {

View File

@ -21,6 +21,7 @@ use crate::storage_utils::StorageAccounts;
use bincode::{deserialize_from, serialize, serialize_into, serialized_size};
use log::*;
use serde::{Deserialize, Serialize};
use solana_measure::measure::Measure;
use solana_metrics::{
datapoint_info, inc_new_counter_debug, inc_new_counter_error, inc_new_counter_info,
};
@ -38,7 +39,7 @@ use solana_sdk::syscall::{
tick_height,
};
use solana_sdk::system_transaction;
use solana_sdk::timing::{duration_as_ms, duration_as_ns, duration_as_us, MAX_RECENT_BLOCKHASHES};
use solana_sdk::timing::{duration_as_ns, MAX_RECENT_BLOCKHASHES};
use solana_sdk::transaction::{Result, Transaction, TransactionError};
use std::cmp;
use std::collections::HashMap;
@ -46,7 +47,6 @@ use std::fmt;
use std::io::{BufReader, Cursor, Read};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::{Arc, RwLock, RwLockReadGuard};
use std::time::Instant;
pub const SECONDS_PER_YEAR: f64 = (365.0 * 24.0 * 60.0 * 60.0);
@ -538,23 +538,23 @@ impl Bank {
let parents = self.parents();
*self.rc.parent.write().unwrap() = None;
let squash_accounts_start = Instant::now();
let mut squash_accounts_time = Measure::start("squash_accounts_time");
for p in parents.iter().rev() {
// root forks cannot be purged
self.rc.accounts.add_root(p.slot());
}
let squash_accounts_ms = duration_as_ms(&squash_accounts_start.elapsed());
squash_accounts_time.stop();
let squash_cache_start = Instant::now();
let mut squash_cache_time = Measure::start("squash_cache_time");
parents
.iter()
.for_each(|p| self.src.status_cache.write().unwrap().add_root(p.slot()));
let squash_cache_ms = duration_as_ms(&squash_cache_start.elapsed());
squash_cache_time.stop();
datapoint_info!(
"tower-observed",
("squash_accounts_ms", squash_accounts_ms, i64),
("squash_cache_ms", squash_cache_ms, i64)
("squash_accounts_ms", squash_accounts_time.as_ms(), i64),
("squash_cache_ms", squash_cache_time.as_ms(), i64)
);
}
@ -946,7 +946,7 @@ impl Bank {
) {
debug!("processing transactions: {}", txs.len());
let mut error_counters = ErrorCounters::default();
let now = Instant::now();
let mut load_time = Measure::start("accounts_load");
let retryable_txs: Vec<_> = lock_results
.locked_accounts_results()
@ -966,9 +966,9 @@ impl Bank {
&mut error_counters,
);
let mut loaded_accounts = self.load_accounts(txs, sig_results, &mut error_counters);
load_time.stop();
let load_elapsed = now.elapsed();
let now = Instant::now();
let mut execution_time = Measure::start("execution_time");
let mut signature_count = 0;
let executed: Vec<Result<()>> = loaded_accounts
.iter_mut()
@ -983,12 +983,12 @@ impl Bank {
})
.collect();
let execution_elapsed = now.elapsed();
execution_time.stop();
debug!(
"load: {}us execute: {}us txs_len={}",
duration_as_us(&load_elapsed),
duration_as_us(&execution_elapsed),
load_time.as_us(),
execution_time.as_us(),
txs.len(),
);
let mut tx_count = 0;
@ -1083,7 +1083,7 @@ impl Bank {
// TODO: put this assert back in
// assert!(!self.is_frozen());
let now = Instant::now();
let mut write_time = Measure::start("write_time");
self.rc
.accounts
.store_accounts(self.slot(), txs, executed, loaded_accounts);
@ -1091,12 +1091,8 @@ impl Bank {
self.update_cached_accounts(txs, executed, loaded_accounts);
// once committed there is no way to unroll
let write_elapsed = now.elapsed();
debug!(
"store: {}us txs_len={}",
duration_as_us(&write_elapsed),
txs.len(),
);
write_time.stop();
debug!("store: {}us txs_len={}", write_time.as_us(), txs.len(),);
self.update_transaction_statuses(txs, &executed);
self.filter_program_errors_and_collect_fee(txs, executed)
}