@@ -25,6 +25,7 @@ const NUM_READERS_WRITERS: &[usize] = &[
25
25
// 32 cores.
26
26
// 32, 64, 128
27
27
] ;
28
+ const EVICT_SAMPLE_SIZES : & [ usize ] = & [ 1 , 2 , 4 , 8 , 10 , 16 , 32 ] ;
28
29
29
30
/// Benchmarks the read-only cache eviction mechanism. It does so by performing
30
31
/// multithreaded reads and writes on a full cache. Each write triggers
@@ -37,106 +38,112 @@ fn bench_cache_eviction(c: &mut Criterion) {
37
38
38
39
let mut group = c. benchmark_group ( "cache_eviction" ) ;
39
40
40
- for num_readers_writers in NUM_READERS_WRITERS {
41
- let cache = Arc :: new ( ReadOnlyAccountsCache :: new (
42
- AccountsDb :: DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_LO ,
43
- AccountsDb :: DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_HI ,
44
- AccountsDb :: READ_ONLY_CACHE_MS_TO_SKIP_LRU_UPDATE ,
45
- ) ) ;
41
+ for evict_sample_size in EVICT_SAMPLE_SIZES {
42
+ for num_readers_writers in NUM_READERS_WRITERS {
43
+ let cache = Arc :: new ( ReadOnlyAccountsCache :: new (
44
+ AccountsDb :: DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_LO ,
45
+ AccountsDb :: DEFAULT_MAX_READ_ONLY_CACHE_DATA_SIZE_HI ,
46
+ * evict_sample_size,
47
+ AccountsDb :: READ_ONLY_CACHE_MS_TO_SKIP_LRU_UPDATE ,
48
+ ) ) ;
46
49
47
- // Prepare accounts for the cache fillup.
48
- let pubkeys: Vec < _ > = std:: iter:: repeat_with ( solana_sdk:: pubkey:: new_rand)
49
- . take ( NUM_ACCOUNTS_INIT )
50
- . collect ( ) ;
51
- let accounts_data = std:: iter:: repeat (
52
- Account {
53
- lamports : 1 ,
54
- // 1 MiB
55
- data : vec ! [ 1 ; 1024 * 1024 ] ,
56
- ..Default :: default ( )
57
- }
58
- . to_account_shared_data ( ) ,
59
- )
60
- . take ( NUM_ACCOUNTS_INIT ) ;
61
- let storable_accounts = pubkeys. iter ( ) . zip ( accounts_data) ;
62
-
63
- // Fill up the cache.
64
- let slot = 0 ;
65
- for ( pubkey, account) in storable_accounts {
66
- cache. store ( * pubkey, slot, account) ;
67
- }
50
+ // Prepare accounts for the cache fillup.
51
+ let pubkeys: Vec < _ > = std:: iter:: repeat_with ( solana_sdk:: pubkey:: new_rand)
52
+ . take ( NUM_ACCOUNTS_INIT )
53
+ . collect ( ) ;
54
+ let accounts_data = std:: iter:: repeat (
55
+ Account {
56
+ lamports : 1 ,
57
+ // 1 MiB
58
+ data : vec ! [ 1 ; 1024 * 1024 ] ,
59
+ ..Default :: default ( )
60
+ }
61
+ . to_account_shared_data ( ) ,
62
+ )
63
+ . take ( NUM_ACCOUNTS_INIT ) ;
64
+ let storable_accounts = pubkeys. iter ( ) . zip ( accounts_data) ;
68
65
69
- // Prepare accounts for the new writes.
70
- let new_storable_accounts = std:: iter:: repeat_with ( solana_sdk:: pubkey:: new_rand)
71
- . map ( |pubkey| {
72
- (
73
- pubkey,
74
- Account {
75
- lamports : 1 ,
76
- // 1 MiB
77
- data : vec ! [ 1 ; 1024 * 1024 ] ,
78
- ..Default :: default ( )
79
- }
80
- . to_account_shared_data ( ) ,
81
- )
82
- } )
83
- . take ( NUM_NEW_ACCOUNTS_PER_THREAD ) ;
66
+ // Fill up the cache.
67
+ let slot = 0 ;
68
+ for ( pubkey, account) in storable_accounts {
69
+ cache. store ( * pubkey, slot, account) ;
70
+ }
84
71
85
- // Spawn the reader threads in the background.
86
- let stop_reader = Arc :: new ( AtomicBool :: new ( false ) ) ;
87
- let reader_handles = ( 0 ..* num_readers_writers) . map ( |i| {
88
- let cache = cache. clone ( ) ;
89
- let pubkeys = pubkeys. clone ( ) ;
90
- let stop_reader = stop_reader. clone ( ) ;
91
- Builder :: new ( )
92
- . name ( format ! ( "reader{i:02}" ) )
93
- . spawn ( {
94
- move || {
95
- // Continuously read random accounts.
96
- let mut rng = SmallRng :: seed_from_u64 ( i as u64 ) ;
97
- while !stop_reader. load ( Ordering :: Relaxed ) {
98
- let pubkey = pubkeys. choose ( & mut rng) . unwrap ( ) ;
99
- test:: black_box ( cache. load ( * pubkey, slot) ) ;
72
+ // Prepare accounts for the new writes.
73
+ let new_storable_accounts = std:: iter:: repeat_with ( solana_sdk:: pubkey:: new_rand)
74
+ . map ( |pubkey| {
75
+ (
76
+ pubkey,
77
+ Account {
78
+ lamports : 1 ,
79
+ // 1 MiB
80
+ data : vec ! [ 1 ; 1024 * 1024 ] ,
81
+ ..Default :: default ( )
100
82
}
101
- }
83
+ . to_account_shared_data ( ) ,
84
+ )
102
85
} )
103
- . unwrap ( )
104
- } ) ;
86
+ . take ( NUM_NEW_ACCOUNTS_PER_THREAD ) ;
105
87
106
- // Benchmark reads and writes on a full cache, trigerring eviction on each
107
- // write.
108
- let slot = 1 ;
109
- group. sample_size ( 10 ) ;
110
- group. bench_function (
111
- BenchmarkId :: new ( "cache_eviction" , num_readers_writers) ,
112
- |b| {
113
- b. iter ( || {
114
- // Perform the writes.
115
- let writer_handles = ( 0 ..* num_readers_writers) . map ( |i| {
116
- let cache = cache. clone ( ) ;
117
- let new_storable_accounts = new_storable_accounts. clone ( ) ;
118
- Builder :: new ( )
119
- . name ( format ! ( "writer{i:02}" ) )
120
- . spawn ( {
121
- move || {
122
- for ( pubkey, account) in new_storable_accounts {
123
- cache. store ( pubkey, slot, account) ;
88
+ // Spawn the reader threads in the background.
89
+ let stop_reader = Arc :: new ( AtomicBool :: new ( false ) ) ;
90
+ let reader_handles = ( 0 ..* num_readers_writers) . map ( |i| {
91
+ let cache = cache. clone ( ) ;
92
+ let pubkeys = pubkeys. clone ( ) ;
93
+ let stop_reader = stop_reader. clone ( ) ;
94
+ Builder :: new ( )
95
+ . name ( format ! ( "reader{i:02}" ) )
96
+ . spawn ( {
97
+ move || {
98
+ // Continuously read random accounts.
99
+ let mut rng = SmallRng :: seed_from_u64 ( i as u64 ) ;
100
+ while !stop_reader. load ( Ordering :: Relaxed ) {
101
+ let pubkey = pubkeys. choose ( & mut rng) . unwrap ( ) ;
102
+ test:: black_box ( cache. load ( * pubkey, slot) ) ;
103
+ }
104
+ }
105
+ } )
106
+ . unwrap ( )
107
+ } ) ;
108
+
109
+ // Benchmark reads and writes on a full cache, trigerring eviction on each
110
+ // write.
111
+ let slot = 1 ;
112
+ group. sample_size ( 10 ) ;
113
+ group. bench_function (
114
+ BenchmarkId :: new (
115
+ format ! ( "cache_eviction_k_{evict_sample_size}" ) ,
116
+ num_readers_writers,
117
+ ) ,
118
+ |b| {
119
+ b. iter ( || {
120
+ // Perform the writes.
121
+ let writer_handles = ( 0 ..* num_readers_writers) . map ( |i| {
122
+ let cache = cache. clone ( ) ;
123
+ let new_storable_accounts = new_storable_accounts. clone ( ) ;
124
+ Builder :: new ( )
125
+ . name ( format ! ( "writer{i:02}" ) )
126
+ . spawn ( {
127
+ move || {
128
+ for ( pubkey, account) in new_storable_accounts {
129
+ cache. store ( pubkey, slot, account) ;
130
+ }
124
131
}
125
- }
126
- } )
127
- . unwrap ( )
128
- } ) ;
132
+ } )
133
+ . unwrap ( )
134
+ } ) ;
129
135
130
- for writer_handle in writer_handles {
131
- writer_handle. join ( ) . unwrap ( ) ;
132
- }
133
- } )
134
- } ,
135
- ) ;
136
+ for writer_handle in writer_handles {
137
+ writer_handle. join ( ) . unwrap ( ) ;
138
+ }
139
+ } )
140
+ } ,
141
+ ) ;
136
142
137
- stop_reader. store ( true , Ordering :: Relaxed ) ;
138
- for reader_handle in reader_handles {
139
- reader_handle. join ( ) . unwrap ( ) ;
143
+ stop_reader. store ( true , Ordering :: Relaxed ) ;
144
+ for reader_handle in reader_handles {
145
+ reader_handle. join ( ) . unwrap ( ) ;
146
+ }
140
147
}
141
148
}
142
149
}
0 commit comments