fn bench_cpu()

in rd-hashd/src/bench.rs [695:785]


    fn bench_cpu(&self, cfg: &CpuCfg) -> usize {
        const TIME_HASH_SIZE: usize = 256 << 20;
        let mut params: Params = self.params.clone();
        let mut nr_rounds = 0;
        let max_size = cfg.size.max(TIME_HASH_SIZE as u64);

        self.set_phase(Phase::BenchCpuSinglePrep);
        let tf = self.prep_tf(max_size, 0, "single cpu bench");
        self.set_phase(Phase::BenchCpuSingle);

        params.concurrency_max = 1;
        params.file_size_stdev_ratio = 0.0;
        params.file_addr_stdev_ratio = 100.0;
        params.anon_size_stdev_ratio = 0.0;
        params.anon_addr_stdev_ratio = 100.0;
        params.sleep_mean = 0.0;
        params.sleep_stdev_ratio = 0.0;

        // Quickly time hash runs to determine the starting point and
        // calculate chunk_pages based on it. Repeat until
        // chunk_pages converges.
        let mut last_chunk_pages = 1;
        let mut nr_converges = 0;
        for _ in 0..10 {
            let base_time = Self::time_hash(TIME_HASH_SIZE, &params, &tf);
            let time_per_byte = base_time / TIME_HASH_SIZE as f64;
            params.file_size_mean = Self::calc_file_size_mean(cfg, &self.params, time_per_byte);

            // chunk_pages calculation must be done with the original
            // params w/ only file_size_mean modified.
            let cup_params = Params {
                file_size_mean: params.file_size_mean,
                ..self.params.clone()
            };
            params.chunk_pages = Self::calc_chunk_pages(cfg, &cup_params);

            if params.chunk_pages == last_chunk_pages {
                nr_converges += 1;
                if nr_converges >= 2 {
                    break;
                }
            } else {
                last_chunk_pages = params.chunk_pages;
                nr_converges = 0;
            }
        }
        params.file_size_mean = (params.file_size_mean as f64 * 1.05) as usize;

        let th = self.create_test_hasher(max_size, tf, &params, true);
        let mut pid = Pid::new(
            cfg.fsz_pid.kp,
            cfg.fsz_pid.ki,
            cfg.fsz_pid.kd,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
        );

        // determine rps based on latency convergence
        while nr_rounds < cfg.rounds {
            nr_rounds += 1;
            info!(
                "[ Single cpu bench: round {}/{}, hash size {:.2}M ]",
                nr_rounds,
                cfg.rounds,
                to_mb(params.file_size_mean)
            );

            let result = th.converge_with_cfg(&cfg.converge);
            let err = (result.0 - cfg.lat) / cfg.lat;

            info!(
                "Latency: {:.2} ~= {:.2}, error: |{:.2}%| <= {:.2}%",
                result.0 * TO_MSEC,
                cfg.lat * TO_MSEC,
                err * TO_PCT,
                cfg.err * TO_PCT
            );
            if err.abs() <= cfg.err {
                break;
            }

            let adj = pid.next_control_output(1.0 + err).output;
            params.file_size_mean = ((params.file_size_mean as f64 * (1.0 + adj)) as usize).max(1);
            th.disp_hist.lock().unwrap().disp.set_params(&params);
        }

        params.file_size_mean
    }