1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#![allow(clippy::integer_arithmetic)]
use clap::{crate_description, crate_name, value_t, App, Arg};
use solana_ledger::entry::{self, create_ticks, init_poh, EntrySlice, VerifyRecyclers};
use solana_measure::measure::Measure;
use solana_perf::perf_libs;
use solana_sdk::hash::hash;

fn main() {
    solana_logger::setup();

    let matches = App::new(crate_name!())
        .about(crate_description!())
        .version(solana_version::version!())
        .arg(
            Arg::with_name("max_num_entries")
                .long("max-num-entries")
                .takes_value(true)
                .value_name("SIZE")
                .help("Number of entries."),
        )
        .arg(
            Arg::with_name("start_num_entries")
                .long("start-num-entries")
                .takes_value(true)
                .value_name("SIZE")
                .help("Packets per chunk"),
        )
        .arg(
            Arg::with_name("hashes_per_tick")
                .long("hashes-per-tick")
                .takes_value(true)
                .value_name("SIZE")
                .help("hashes per tick"),
        )
        .arg(
            Arg::with_name("num_transactions_per_entry")
                .long("num-transactions-per-entry")
                .takes_value(true)
                .value_name("NUM")
                .help("Skip transaction sanity execution"),
        )
        .arg(
            Arg::with_name("iterations")
                .long("iterations")
                .takes_value(true)
                .help("Number of iterations"),
        )
        .arg(
            Arg::with_name("num_threads")
                .long("num-threads")
                .takes_value(true)
                .help("Number of threads"),
        )
        .arg(
            Arg::with_name("cuda")
                .long("cuda")
                .takes_value(false)
                .help("Use cuda"),
        )
        .get_matches();

    let max_num_entries = value_t!(matches, "max_num_entries", u64).unwrap_or(64);
    let start_num_entries = value_t!(matches, "start_num_entries", u64).unwrap_or(max_num_entries);
    let iterations = value_t!(matches, "iterations", usize).unwrap_or(10);
    let hashes_per_tick = value_t!(matches, "hashes_per_tick", u64).unwrap_or(10_000);
    let start_hash = hash(&[1, 2, 3, 4]);
    let ticks = create_ticks(max_num_entries, hashes_per_tick, start_hash);
    let mut num_entries = start_num_entries as usize;
    if matches.is_present("cuda") {
        perf_libs::init_cuda();
    }
    init_poh();
    while num_entries <= max_num_entries as usize {
        let mut time = Measure::start("time");
        for _ in 0..iterations {
            assert!(ticks[..num_entries]
                .verify_cpu_generic(&start_hash)
                .finish_verify(&ticks[..num_entries]));
        }
        time.stop();
        println!(
            "{},cpu_generic,{}",
            num_entries,
            time.as_us() / iterations as u64
        );

        if is_x86_feature_detected!("avx2") && entry::api().is_some() {
            let mut time = Measure::start("time");
            for _ in 0..iterations {
                assert!(ticks[..num_entries]
                    .verify_cpu_x86_simd(&start_hash, 8)
                    .finish_verify(&ticks[..num_entries]));
            }
            time.stop();
            println!(
                "{},cpu_simd_avx2,{}",
                num_entries,
                time.as_us() / iterations as u64
            );
        }

        if is_x86_feature_detected!("avx512f") && entry::api().is_some() {
            let mut time = Measure::start("time");
            for _ in 0..iterations {
                assert!(ticks[..num_entries]
                    .verify_cpu_x86_simd(&start_hash, 16)
                    .finish_verify(&ticks[..num_entries]));
            }
            time.stop();
            println!(
                "{},cpu_simd_avx512,{}",
                num_entries,
                time.as_us() / iterations as u64
            );
        }

        if perf_libs::api().is_some() {
            let mut time = Measure::start("time");
            let recyclers = VerifyRecyclers::default();
            for _ in 0..iterations {
                assert!(ticks[..num_entries]
                    .start_verify(&start_hash, recyclers.clone(), true)
                    .finish_verify(&ticks[..num_entries]));
            }
            time.stop();
            println!(
                "{},gpu_cuda,{}",
                num_entries,
                time.as_us() / iterations as u64
            );
        }

        println!();
        num_entries *= 2;
    }
}