From d0a834850a0e380d3eb5387ed8927690ae4eb879 Mon Sep 17 00:00:00 2001 From: Michal Rostecki Date: Thu, 2 Jan 2025 15:18:55 +0100 Subject: [PATCH] accounts-db: Improve sharding of the read-only cache The default amount of shards in `DashMap` is `num_cpus * 4`. That means 256 on validators with 64 threads. A number of accounts held in caches on mainnet beta validators with default configuration is around 44-56K, which results in around 200 accounts per shard. That means, locking a shard locks an access to 200 accounts. Fix that by increasing the amount of shards to 65536, which in the best case will keep just one account per shard. Acquiring a lock shouldn't lock access to any other accounts. A single `RwLock>`, without the key and value included, takes 48 bytes. Therefore, 65536 shards are taking 3145728 B, which rounds up to 3MB. It's an acceptable increase in memopry usage. --- accounts-db/src/read_only_accounts_cache.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/accounts-db/src/read_only_accounts_cache.rs b/accounts-db/src/read_only_accounts_cache.rs index 79581ee55edc41..57185b1c744561 100644 --- a/accounts-db/src/read_only_accounts_cache.rs +++ b/accounts-db/src/read_only_accounts_cache.rs @@ -31,6 +31,11 @@ use { const CACHE_ENTRY_SIZE: usize = std::mem::size_of::() + 2 * std::mem::size_of::(); +/// Number of cache shards. This number is close to the number of accounts +/// in cache observed on mainnet beta validators, therefore it should result +/// in each accout having its own shard and reduced amount of locks. +const SHARDS: usize = 65536; + type ReadOnlyCacheKey = Pubkey; #[derive(Debug)] @@ -98,7 +103,7 @@ impl ReadOnlyAccountsCache { ) -> Self { assert!(max_data_size_lo <= max_data_size_hi); assert!(evict_sample_size > 0); - let cache = Arc::new(DashMap::default()); + let cache = Arc::new(DashMap::with_shard_amount(SHARDS)); let data_size = Arc::new(AtomicUsize::default()); let stats = Arc::new(AtomicReadOnlyCacheStats::default()); let evictor_exit_flag = Arc::new(AtomicBool::new(false));