|
| 1 | +#include "fd_funk.h" |
| 2 | +#include "fd_funk_base.h" |
| 3 | + |
| 4 | +#define FUNK_TAG 1UL |
| 5 | + |
| 6 | +__attribute__((noinline)) static void |
| 7 | +run_benchmark( fd_funk_t * funk, |
| 8 | + fd_rng_t * rng, |
| 9 | + ulong acc_cnt ) { |
| 10 | + fd_wksp_t * funk_wksp = fd_funk_wksp( funk ); |
| 11 | + ulong acc_rem=acc_cnt; |
| 12 | + while( acc_rem-- ) { |
| 13 | + fd_funk_rec_key_t key; |
| 14 | + key.ul[ 0 ] = fd_rng_ulong( rng ); |
| 15 | + fd_funk_rec_prepare_t prepare[1]; |
| 16 | + fd_funk_rec_t * rec = fd_funk_rec_prepare( funk, NULL, &key, prepare, NULL ); |
| 17 | + FD_TEST( rec ); |
| 18 | + fd_funk_val_truncate( rec, 104, fd_funk_alloc( funk, funk_wksp ), funk_wksp, NULL ); |
| 19 | + fd_funk_rec_publish( prepare ); |
| 20 | + } |
| 21 | +} |
| 22 | + |
| 23 | +static void |
| 24 | +stat_chains( fd_funk_t * funk ) { |
| 25 | + fd_funk_rec_map_t rec_map = fd_funk_rec_map( funk, fd_funk_wksp( funk ) ); |
| 26 | + fd_funk_rec_map_shmem_private_chain_t * chain_tbl = fd_funk_rec_map_shmem_private_chain( rec_map.map, 0UL ); |
| 27 | + ulong chain_cnt = fd_funk_rec_map_chain_cnt( &rec_map ); |
| 28 | + |
| 29 | + double sum = 0.0; |
| 30 | + ulong min = ULONG_MAX; |
| 31 | + ulong max = 0UL; |
| 32 | + for( ulong chain_idx=0UL; chain_idx<chain_cnt; chain_idx++ ) { |
| 33 | + ulong chain_len = fd_funk_rec_map_private_vcnt_cnt( chain_tbl[ chain_idx ].ver_cnt ); |
| 34 | + sum += (double)chain_len; |
| 35 | + min = fd_ulong_min( min, chain_len ); |
| 36 | + max = fd_ulong_max( max, chain_len ); |
| 37 | + } |
| 38 | + double mean = sum / (double)chain_cnt; |
| 39 | + double var = 0.0; |
| 40 | + for( ulong chain_idx=0UL; chain_idx<chain_cnt; chain_idx++ ) { |
| 41 | + double diff = (double)fd_funk_rec_map_private_vcnt_cnt( chain_tbl[ chain_idx ].ver_cnt ) - mean; |
| 42 | + var += diff*diff; |
| 43 | + } |
| 44 | + var /= (double)chain_cnt; |
| 45 | + FD_LOG_NOTICE(( "Chain lengths: min=%lu max=%lu mean=%.2f var=%.2f stddev=%.2f", |
| 46 | + min, max, (double)mean, (double)var, (double)sqrt(var) )); |
| 47 | +} |
| 48 | + |
| 49 | +int |
| 50 | +main( int argc, |
| 51 | + char ** argv ) { |
| 52 | + fd_boot( &argc, &argv ); |
| 53 | + |
| 54 | + char const * name = fd_env_strip_cmdline_cstr ( &argc, &argv, "--wksp", NULL, NULL ); |
| 55 | + char const * _page_sz = fd_env_strip_cmdline_cstr ( &argc, &argv, "--page-sz", NULL, "gigantic" ); |
| 56 | + ulong page_cnt = fd_env_strip_cmdline_ulong ( &argc, &argv, "--page-cnt", NULL, 3UL ); |
| 57 | + ulong near_cpu = fd_env_strip_cmdline_ulong ( &argc, &argv, "--near-cpu", NULL, fd_log_cpu_id() ); |
| 58 | + double acc_cnt_d = fd_env_strip_cmdline_double( &argc, &argv, "--accounts", NULL, 1e9 ); |
| 59 | + double rec_max_d = fd_env_strip_cmdline_double( &argc, &argv, "--rec-max", NULL, 1e9 ); |
| 60 | + uint rng_seed = fd_env_strip_cmdline_uint ( &argc, &argv, "--rng-seed", NULL, 1234UL ); |
| 61 | + ulong funk_seed = fd_env_strip_cmdline_ulong ( &argc, &argv, "--funk-seed", NULL, 1234UL ); |
| 62 | + int fast_clean = fd_env_strip_cmdline_int ( &argc, &argv, "--fast-clean", NULL, 1 ); |
| 63 | + |
| 64 | + ulong const txn_max = 16UL; |
| 65 | + ulong const acc_cnt = (ulong)acc_cnt_d; |
| 66 | + uint const rec_max = (uint)rec_max_d; |
| 67 | + |
| 68 | + fd_rng_t rng_[1]; |
| 69 | + fd_rng_t * rng = fd_rng_join( fd_rng_new( rng_, rng_seed, 0UL ) ); |
| 70 | + |
| 71 | + ulong page_sz = fd_cstr_to_shmem_page_sz( _page_sz ); |
| 72 | + if( FD_UNLIKELY( !page_sz ) ) FD_LOG_ERR(( "unsupported --page-sz" )); |
| 73 | + |
| 74 | + ulong funk_footprint = fd_funk_footprint( txn_max, rec_max ); |
| 75 | + FD_LOG_NOTICE(( "fd_funk_footprint(txn_max=%lu,rec_max=%g) = %.1f MiB", txn_max, (double)rec_max, (double)funk_footprint/(1024.0*1024.0) )); |
| 76 | + ulong chain_cnt = fd_funk_rec_map_chain_cnt_est( rec_max ); |
| 77 | + FD_LOG_NOTICE(( "fd_funk_rec_map_chain_cnt_est(rec_max=%g) = %g", (double)rec_max, (double)chain_cnt )); |
| 78 | + if( FD_UNLIKELY( funk_footprint > (page_cnt*page_sz ) ) ) FD_LOG_ERR(( "funk footprint exceeds memory bounds" )); |
| 79 | + |
| 80 | + fd_wksp_t * wksp; |
| 81 | + if( name ) { |
| 82 | + FD_LOG_NOTICE(( "Attaching to --wksp %s", name )); |
| 83 | + wksp = fd_wksp_attach( name ); |
| 84 | + } else { |
| 85 | + FD_LOG_NOTICE(( "--wksp not specified, using an anonymous local workspace, --page-sz %s, --page-cnt %lu, --near-cpu %lu", |
| 86 | + _page_sz, page_cnt, near_cpu )); |
| 87 | + wksp = fd_wksp_new_anonymous( fd_cstr_to_shmem_page_sz( _page_sz ), page_cnt, near_cpu, "wksp", 0UL ); |
| 88 | + } |
| 89 | + |
| 90 | + void * funk_mem = fd_wksp_alloc_laddr( wksp, fd_funk_align(), funk_footprint, FUNK_TAG ); |
| 91 | + if( FD_UNLIKELY( !funk_mem ) ) FD_LOG_ERR(( "failed to allocate funk" )); |
| 92 | + fd_funk_t * funk = fd_funk_join( fd_funk_new( funk_mem, FUNK_TAG, funk_seed, 16UL, rec_max ) ); |
| 93 | + |
| 94 | + fd_funk_rec_map_t rec_map = fd_funk_rec_map( funk, wksp ); |
| 95 | + FD_TEST( fd_funk_rec_map_chain_cnt( &rec_map ) == chain_cnt ); |
| 96 | + |
| 97 | + FD_LOG_NOTICE(( "Starting insert loop" )); |
| 98 | + long dt = -fd_log_wallclock(); |
| 99 | + run_benchmark( funk, rng, acc_cnt ); |
| 100 | + dt += fd_log_wallclock(); |
| 101 | + FD_LOG_NOTICE(( "Inserted %lu accounts in %.2fs (rate=%.2g per_item=%.0fns)", |
| 102 | + acc_cnt, (double)dt/1e9, |
| 103 | + (double)acc_cnt/( (double)dt/1e9 ), |
| 104 | + (double)dt/(double)acc_cnt )); |
| 105 | + |
| 106 | + stat_chains( funk ); |
| 107 | + |
| 108 | + dt = -fd_log_wallclock(); |
| 109 | + if( fast_clean ) { |
| 110 | + ulong const tags[1] = { FUNK_TAG }; |
| 111 | + fd_wksp_tag_free( wksp, tags, 1UL ); |
| 112 | + } else { |
| 113 | + fd_wksp_free_laddr( fd_funk_delete( fd_funk_leave( funk ) ) ); |
| 114 | + } |
| 115 | + if( name ) fd_wksp_detach( wksp ); |
| 116 | + else fd_wksp_delete_anonymous( wksp ); |
| 117 | + fd_rng_delete( fd_rng_leave( rng ) ); |
| 118 | + dt += fd_log_wallclock(); |
| 119 | + FD_LOG_NOTICE(( "Clean up took %.1fs", (double)dt/1e9 )); |
| 120 | + |
| 121 | + FD_LOG_NOTICE(( "pass" )); |
| 122 | + fd_halt(); |
| 123 | + return 0; |
| 124 | +} |
0 commit comments