Skip to content

Commit b297342

Browse files
committed
bench: firedancer integration
1 parent fb674ce commit b297342

File tree

38 files changed

+234
-130
lines changed

38 files changed

+234
-130
lines changed

book/api/metrics-generated.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,3 +1106,13 @@
11061106
| <span class="metrics-name">snapwr_&#8203;vinyl_&#8203;bytes_&#8203;written</span> | gauge | Number of bytes written so far to the vinyl snapshot file. Might decrease if snapshot creation is aborted and restarted |
11071107

11081108
</div>
1109+
1110+
## Benchs Tile
1111+
1112+
<div class="metrics">
1113+
1114+
| Metric | Type | Description |
1115+
|--------|------|-------------|
1116+
| <span class="metrics-name">benchs_&#8203;transactions_&#8203;sent</span> | counter | Number of benchmark packets sent |
1117+
1118+
</div>

src/app/fddev/commands/bench.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ agave_thread_main( void * _args ) {
2020
void
2121
fddev_bench_cmd_fn( args_t * args,
2222
config_t * config ) {
23-
bench_cmd_fn( args, config );
23+
bench_cmd_fn( args, config, 0 );
2424

2525
pthread_t agave;
2626
pthread_create( &agave, NULL, agave_thread_main, (void *)config );

src/app/firedancer-dev/commands/backtest.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ backtest_topo( config_t * config ) {
261261

262262
/* banks_obj shared by replay and exec tiles */
263263
fd_topob_wksp( topo, "banks" );
264-
fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width );
264+
fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width, 0 );
265265
fd_topob_tile_uses( topo, replay_tile, banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
266266
FOR(exec_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
267267
FD_TEST( fd_pod_insertf_ulong( topo->props, banks_obj->id, "banks" ) );

src/app/firedancer-dev/commands/bench.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@
33

44
#include <unistd.h>
55

6+
static void
7+
bench_cmd_topo( config_t * config ) {
8+
config->development.sandbox = 0;
9+
config->development.no_clone = 1;
10+
}
11+
612
void
713
firedancer_dev_bench_cmd_fn( args_t * args,
814
config_t * config ) {
9-
bench_cmd_fn( args, config );
15+
bench_cmd_fn( args, config, 1 );
1016

1117
/* Sleep parent thread forever, Ctrl+C will terminate. */
1218
for(;;) pause();
@@ -17,6 +23,7 @@ action_t fd_action_bench = {
1723
.args = bench_cmd_args,
1824
.fn = firedancer_dev_bench_cmd_fn,
1925
.perm = dev_cmd_perm,
26+
.topo = bench_cmd_topo,
2027
.is_local_cluster = 1,
2128
.description = "Test validator TPS benchmark"
2229
};

src/app/firedancer-dev/commands/sim.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ sim_topo( config_t * config ) {
126126
config->firedancer.runtime.max_live_slots,
127127
fd_ulong_pow2_up( FD_PACK_MAX_TXNCACHE_TXN_PER_SLOT ) );
128128
fd_topo_obj_t * poh_slot_obj = fd_topob_obj( topo, "fseq", "poh_slot" );
129-
fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width );
129+
fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width, 0 );
130130

131131
FD_TEST( fd_pod_insertf_ulong( topo->props, poh_shred_obj->id, "poh_shred" ) );
132132
FD_TEST( fd_pod_insertf_ulong( topo->props, root_slot_obj->id, "root_slot" ) );

src/app/firedancer/callbacks.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ banks_align( fd_topo_t const * topo FD_FN_UNUSED,
2626
static void
2727
banks_new( fd_topo_t const * topo,
2828
fd_topo_obj_t const * obj ) {
29-
FD_TEST( fd_banks_new( fd_topo_obj_laddr( topo, obj->id ), VAL("max_live_slots"), VAL("max_fork_width") ) );
29+
int larger_max_cost_per_block = fd_pod_queryf_int( topo->props, 0, "obj.%lu.larger_max_cost_per_block", obj->id );
30+
ulong seed = fd_pod_queryf_ulong( topo->props, 0UL, "obj.%lu.seed", obj->id );
31+
FD_TEST( fd_banks_new( fd_topo_obj_laddr( topo, obj->id ), VAL("max_live_slots"), VAL("max_fork_width"), larger_max_cost_per_block, seed ) );
3032
}
3133

3234
fd_topo_obj_callbacks_t fd_obj_cb_banks = {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# A suggested configuration for benchmarking on a Zen3 CPU like AMD EPYC
2+
# 7513 or similar. The configuration expects 64 logical cores, and 32
3+
# physical cores, numbered 0 and 1 for thread 0 and thread 1 on core 0,
4+
# 2 and 3 for thread 0 and thread 1 on core 1, and so on. In
5+
# production, the configuration would not be correct as cores do not
6+
# need to be dedicated to generating and sending transactions for
7+
# benchmarking.
8+
[layout]
9+
affinity = "14-63,f1"
10+
net_tile_count = 1
11+
quic_tile_count = 1
12+
resolv_tile_count = 1
13+
verify_tile_count = 20
14+
gossvf_tile_count = 1
15+
bank_tile_count = 4
16+
exec_tile_count = 1
17+
shred_tile_count = 1
18+
sign_tile_count = 2
19+
20+
[development.genesis]
21+
fund_initial_accounts = 32768
22+
23+
[development.bench]
24+
benchg_tile_count = 12
25+
benchs_tile_count = 2
26+
affinity = "f1,0-13"
27+
larger_max_cost_per_block = true
28+
larger_shred_limits_per_block = true
29+
30+
[tiles.shred]
31+
max_pending_shred_sets = 16384
32+
33+
[tiles.pack]
34+
schedule_strategy = "perf"

src/app/firedancer/topology.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,15 @@ fd_topo_obj_t *
5959
setup_topo_banks( fd_topo_t * topo,
6060
char const * wksp_name,
6161
ulong max_live_slots,
62-
ulong max_fork_width ) {
62+
ulong max_fork_width,
63+
int larger_max_cost_per_block ) {
6364
fd_topo_obj_t * obj = fd_topob_obj( topo, "banks", wksp_name );
6465
FD_TEST( fd_pod_insertf_ulong( topo->props, max_live_slots, "obj.%lu.max_live_slots", obj->id ) );
6566
FD_TEST( fd_pod_insertf_ulong( topo->props, max_fork_width, "obj.%lu.max_fork_width", obj->id ) );
67+
FD_TEST( fd_pod_insertf_int( topo->props, larger_max_cost_per_block, "obj.%lu.larger_max_cost_per_block", obj->id ) );
68+
ulong seed;
69+
FD_TEST( fd_rng_secure( &seed, sizeof( ulong ) ) );
70+
FD_TEST( fd_pod_insertf_ulong( topo->props, seed, "obj.%lu.seed", obj->id ) );
6671
return obj;
6772
}
6873

@@ -809,7 +814,7 @@ fd_topo_initialize( config_t * config ) {
809814
FOR(bank_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "bank", i ) ], funk_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
810815
FOR(resolv_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "resolv", i ) ], funk_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
811816

812-
fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width );
817+
fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width, config->development.bench.larger_max_cost_per_block );
813818
/**/ fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "replay", 0UL ) ], banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE ); /* TODO: Should be readonly? */
814819
FOR(exec_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE ); /* TODO: Should be readonly? */
815820
FOR(bank_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "bank", i ) ], banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
@@ -1091,6 +1096,8 @@ fd_topo_configure_tile( fd_topo_tile_t * tile,
10911096

10921097
tile->replay.expected_shred_version = config->consensus.expected_shred_version;
10931098

1099+
tile->replay.larger_max_cost_per_block = config->development.bench.larger_max_cost_per_block;
1100+
10941101
/* not specified by [tiles.replay] */
10951102

10961103
strncpy( tile->replay.identity_key_path, config->paths.identity_key, sizeof(tile->replay.identity_key_path) );

src/app/firedancer/topology.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ fd_topo_obj_t *
2020
setup_topo_banks( fd_topo_t * topo,
2121
char const * wksp_name,
2222
ulong max_live_slots,
23-
ulong max_fork_width );
23+
ulong max_fork_width,
24+
int larger_max_cost_per_block );
2425

2526
fd_topo_obj_t *
2627
setup_topo_funk( fd_topo_t * topo,

src/app/shared/commands/watch/watch.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ total_regime( ulong const * metrics ) {
173173
return sum;
174174
}
175175

176+
static ulong tps_sent_samples_idx = 0UL;
177+
static ulong tps_sent_samples[ 200UL ];
176178
static ulong sps_samples_idx = 0UL;
177179
static ulong sps_samples[ 200UL ];
178180
static ulong tps_samples_idx = 0UL;
@@ -213,6 +215,45 @@ static ulong snapshot_acc_samples[ 100UL ];
213215
fmt_countf( fd_alloca_check( 1UL, 64UL ), 64UL, count ); \
214216
}))
215217

218+
static int
219+
write_bench( config_t const * config,
220+
ulong const * cur_tile,
221+
ulong const * prev_tile ) {
222+
if( FD_UNLIKELY( fd_topo_find_tile( &config->topo, "benchs", 0UL )==ULONG_MAX ) ) return 0;
223+
224+
ulong tps_sum = 0UL;
225+
ulong num_tps_samples = fd_ulong_min( tps_sent_samples_idx, sizeof(tps_sent_samples)/sizeof(tps_sent_samples[0]));
226+
for( ulong i=0UL; i<num_tps_samples; i++ ) tps_sum += tps_sent_samples[ i ];
227+
char * tps_str = COUNTF( 100.0*(double)tps_sum/(double)num_tps_samples );
228+
229+
PRINT( "🌶 \033[1m\033[92mBENCH.......\033[0m\033[22m \033[1mGENERATED TPS\033[22m %s \033[1mBENCHG BUSY\033[22m", tps_str );
230+
for( ulong i=0UL; i<config->topo.tile_cnt; i++ ) {
231+
if( FD_LIKELY( strcmp( config->topo.tiles[ i ].name, "benchg" ) ) ) continue;
232+
233+
ulong total_ticks = total_regime( &cur_tile[ i*FD_METRICS_TOTAL_SZ ] )-total_regime( &prev_tile[ i*FD_METRICS_TOTAL_SZ ] );
234+
double backp_pct = 100.0*(double)( diff_tile( config, "benchg", prev_tile, cur_tile, MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_BACKPRESSURE_PREFRAG ) ) )/(double)total_ticks;
235+
double idle_pct = 100.0*(double)( diff_tile( config, "benchg", prev_tile, cur_tile, MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_POSTFRAG ) ) )/(double)total_ticks;
236+
double busy_pct = 100.0 - idle_pct - backp_pct;
237+
238+
PRINT( " %.1f %%", busy_pct );
239+
}
240+
241+
PRINT( " \033[1mBENCHS BUSY\033[22m" );
242+
for( ulong i=0UL; i<config->topo.tile_cnt; i++ ) {
243+
if( FD_LIKELY( strcmp( config->topo.tiles[ i ].name, "benchs" ) ) ) continue;
244+
245+
ulong total_ticks = total_regime( &cur_tile[ i*FD_METRICS_TOTAL_SZ ] )-total_regime( &prev_tile[ i*FD_METRICS_TOTAL_SZ ] );
246+
double backp_pct = 100.0*(double)( diff_tile( config, "benchs", prev_tile, cur_tile, MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_BACKPRESSURE_PREFRAG ) ) )/(double)total_ticks;
247+
double idle_pct = 100.0*(double)( diff_tile( config, "benchs", prev_tile, cur_tile, MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_POSTFRAG ) ) )/(double)total_ticks;
248+
double busy_pct = 100.0 - idle_pct - backp_pct;
249+
250+
PRINT( " %.1f %%", busy_pct );
251+
}
252+
253+
PRINT( "\033[K\n" );
254+
return 1;
255+
}
256+
216257
static void
217258
write_backtest( config_t const * config,
218259
ulong const * cur_tile ) {
@@ -397,7 +438,7 @@ write_replay( config_t const * config,
397438
for( ulong i=0UL; i<num_tps_samples; i++ ) tps_sum += tps_samples[ i ];
398439
char * tps_str = COUNTF( 100.0*(double)tps_sum/(double)num_tps_samples );
399440

400-
PRINT( "💥 \033[1m\033[35mREPLAY......\033[0m\033[22m \033[1mSLOT\033[22m %lu (%ld) \033[1mTPS\033[22m %s \033[1mSPS\033[22m %s \033[1mLEADER IN\033[22m %s \033[1mROOT DIST\033[22m %lu \033[1mBANKS\033[22m %lu\033[K\n",
441+
PRINT( "💥 \033[1m\033[35mREPLAY......\033[0m\033[22m \033[1mSLOT\033[22m %lu (%02ld) \033[1mTPS\033[22m %s \033[1mSPS\033[22m %s \033[1mLEADER IN\033[22m %s \033[1mROOT DIST\033[22m %lu \033[1mBANKS\033[22m %lu\033[K\n",
401442
reset_slot,
402443
(long)reset_slot-(long)turbine_slot,
403444
tps_str,
@@ -433,6 +474,8 @@ write_summary( config_t const * config,
433474

434475
lines_printed = 1UL;
435476

477+
if( FD_UNLIKELY( write_bench( config, cur_tile, prev_tile ) ) ) lines_printed++;
478+
436479
ulong backt_idx = fd_topo_find_tile( &config->topo, "backt", 0UL );
437480
if( FD_UNLIKELY( backt_idx!=ULONG_MAX ) ) {
438481
lines_printed++;
@@ -527,6 +570,9 @@ run( config_t const * config,
527570
snap_tiles( &config->topo, tiles+last_snap*tile_cnt*FD_METRICS_TOTAL_SZ );
528571
snap_links( &config->topo, links+last_snap*(cons_cnt*8UL*FD_METRICS_ALL_LINK_IN_TOTAL) );
529572

573+
tps_sent_samples[ tps_sent_samples_idx%(sizeof(tps_sent_samples)/sizeof(tps_sent_samples[0])) ] = (ulong)diff_tile( config, "benchs", tiles+(1UL-last_snap)*tile_cnt*FD_METRICS_TOTAL_SZ, tiles+last_snap*tile_cnt*FD_METRICS_TOTAL_SZ, MIDX( COUNTER, BENCHS, TRANSACTIONS_SENT ) );
574+
tps_sent_samples_idx++;
575+
530576
sps_samples[ sps_samples_idx%(sizeof(sps_samples)/sizeof(sps_samples[0])) ] = (ulong)diff_tile( config, "replay", tiles+(1UL-last_snap)*tile_cnt*FD_METRICS_TOTAL_SZ, tiles+last_snap*tile_cnt*FD_METRICS_TOTAL_SZ, MIDX( COUNTER, REPLAY, SLOTS_TOTAL ) );
531577
sps_samples_idx++;
532578
tps_samples[ tps_samples_idx%(sizeof(tps_samples)/sizeof(tps_samples[0])) ] = (ulong)diff_tile( config, "replay", tiles+(1UL-last_snap)*tile_cnt*FD_METRICS_TOTAL_SZ, tiles+last_snap*tile_cnt*FD_METRICS_TOTAL_SZ, MIDX( COUNTER, REPLAY, TRANSACTIONS_TOTAL ) );

0 commit comments

Comments
 (0)