cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

benchmark.c (4924B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*  cpufreq-bench CPUFreq microbenchmark
      3 *
      4 *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
      5 */
      6
      7#include <stdio.h>
      8#include <unistd.h>
      9#include <math.h>
     10
     11#include "config.h"
     12#include "system.h"
     13#include "benchmark.h"
     14
     15/* Print out progress if we log into a file */
     16#define show_progress(total_time, progress_time)	\
     17if (config->output != stdout) {				\
     18	fprintf(stdout, "Progress: %02lu %%\r",		\
     19		(progress_time * 100) / total_time);	\
     20	fflush(stdout);					\
     21}
     22
     23/**
     24 * compute how many rounds of calculation we should do
     25 * to get the given load time
     26 *
     27 * @param load aimed load time in µs
     28 *
     29 * @retval rounds of calculation
     30 **/
     31
     32unsigned int calculate_timespace(long load, struct config *config)
     33{
     34	int i;
     35	long long now, then;
     36	unsigned int estimated = GAUGECOUNT;
     37	unsigned int rounds = 0;
     38	unsigned int timed = 0;
     39
     40	if (config->verbose)
     41		printf("calibrating load of %lius, please wait...\n", load);
     42
     43	/* get the initial calculation time for a specific number of rounds */
     44	now = get_time();
     45	ROUNDS(estimated);
     46	then = get_time();
     47
     48	timed = (unsigned int)(then - now);
     49
     50	/* approximation of the wanted load time by comparing with the
     51	 * initial calculation time */
     52	for (i = 0; i < 4; i++) {
     53		rounds = (unsigned int)(load * estimated / timed);
     54		dprintf("calibrating with %u rounds\n", rounds);
     55		now = get_time();
     56		ROUNDS(rounds);
     57		then = get_time();
     58
     59		timed = (unsigned int)(then - now);
     60		estimated = rounds;
     61	}
     62	if (config->verbose)
     63		printf("calibration done\n");
     64
     65	return estimated;
     66}
     67
     68/**
     69 * benchmark
     70 * generates a specific sleep an load time with the performance
     71 * governor and compares the used time for same calculations done
     72 * with the configured powersave governor
     73 *
     74 * @param config config values for the benchmark
     75 *
     76 **/
     77
     78void start_benchmark(struct config *config)
     79{
     80	unsigned int _round, cycle;
     81	long long now, then;
     82	long sleep_time = 0, load_time = 0;
     83	long performance_time = 0, powersave_time = 0;
     84	unsigned int calculations;
     85	unsigned long total_time = 0, progress_time = 0;
     86
     87	sleep_time = config->sleep;
     88	load_time = config->load;
     89
     90	/* For the progress bar */
     91	for (_round = 1; _round <= config->rounds; _round++)
     92		total_time += _round * (config->sleep + config->load);
     93	total_time *= 2; /* powersave and performance cycles */
     94
     95	for (_round = 0; _round < config->rounds; _round++) {
     96		performance_time = 0LL;
     97		powersave_time = 0LL;
     98
     99		show_progress(total_time, progress_time);
    100
    101		/* set the cpufreq governor to "performance" which disables
    102		 * P-State switching. */
    103		if (set_cpufreq_governor("performance", config->cpu) != 0)
    104			return;
    105
    106		/* calibrate the calculation time. the resulting calculation
    107		 * _rounds should produce a load which matches the configured
    108		 * load time */
    109		calculations = calculate_timespace(load_time, config);
    110
    111		if (config->verbose)
    112			printf("_round %i: doing %u cycles with %u calculations"
    113			       " for %lius\n", _round + 1, config->cycles,
    114			       calculations, load_time);
    115
    116		fprintf(config->output, "%u %li %li ",
    117			_round, load_time, sleep_time);
    118
    119		if (config->verbose)
    120			printf("average: %lius, rps:%li\n",
    121				load_time / calculations,
    122				1000000 * calculations / load_time);
    123
    124		/* do some sleep/load cycles with the performance governor */
    125		for (cycle = 0; cycle < config->cycles; cycle++) {
    126			now = get_time();
    127			usleep(sleep_time);
    128			ROUNDS(calculations);
    129			then = get_time();
    130			performance_time += then - now - sleep_time;
    131			if (config->verbose)
    132				printf("performance cycle took %lius, "
    133					"sleep: %lius, "
    134					"load: %lius, rounds: %u\n",
    135					(long)(then - now), sleep_time,
    136					load_time, calculations);
    137		}
    138		fprintf(config->output, "%li ",
    139			performance_time / config->cycles);
    140
    141		progress_time += sleep_time + load_time;
    142		show_progress(total_time, progress_time);
    143
    144		/* set the powersave governor which activates P-State switching
    145		 * again */
    146		if (set_cpufreq_governor(config->governor, config->cpu) != 0)
    147			return;
    148
    149		/* again, do some sleep/load cycles with the
    150		 * powersave governor */
    151		for (cycle = 0; cycle < config->cycles; cycle++) {
    152			now = get_time();
    153			usleep(sleep_time);
    154			ROUNDS(calculations);
    155			then = get_time();
    156			powersave_time += then - now - sleep_time;
    157			if (config->verbose)
    158				printf("powersave cycle took %lius, "
    159					"sleep: %lius, "
    160					"load: %lius, rounds: %u\n",
    161					(long)(then - now), sleep_time,
    162					load_time, calculations);
    163		}
    164
    165		progress_time += sleep_time + load_time;
    166
    167		/* compare the average sleep/load cycles  */
    168		fprintf(config->output, "%li ",
    169			powersave_time / config->cycles);
    170		fprintf(config->output, "%.3f\n",
    171			performance_time * 100.0 / powersave_time);
    172		fflush(config->output);
    173
    174		if (config->verbose)
    175			printf("performance is at %.2f%%\n",
    176				performance_time * 100.0 / powersave_time);
    177
    178		sleep_time += config->sleep_step;
    179		load_time += config->load_step;
    180	}
    181}