Skip to content

Commit

Permalink
MT#56374 more options for perf-tester
Browse files Browse the repository at this point in the history
Change-Id: Iefe137216950e969e7e28284ac57032cf06a2904
  • Loading branch information
rfuchs committed Sep 6, 2023
1 parent 8684a19 commit 2aa8520
Showing 1 changed file with 144 additions and 5 deletions.
149 changes: 144 additions & 5 deletions perf-tester/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ struct other_thread {
struct stats stats; // temp storage, owned by output thread
};

struct freq_stats {
long min;
long max;
long sum;
long samples;
};

struct thread_freq_stats {
mutex_t lock;
struct freq_stats stats;
};


typedef void render_fn(const struct stats *stats, int line, int x, int breadth, int width,
int color,
Expand Down Expand Up @@ -141,6 +153,11 @@ static int init_threads = 0;
static bool bidirectional = false;
static int max_cpu = 0;
static bool system_cpu;
static int break_in = 200;
static int measure_time = 500;
static int repeats = 1;
static bool cpu_freq;
static int freq_granularity = 50;


#define BLOCKED_COLOR 1
Expand Down Expand Up @@ -1512,6 +1529,36 @@ static void options(int *argc, char ***argv) {
.arg_data = &system_cpu,
.description = "Consider system CPU usage for automated tests",
},
{
.long_name = "break-in",
.arg = G_OPTION_ARG_INT,
.arg_data = &break_in,
.description = "Break-in time in ms before measuring for automated tests",
},
{
.long_name = "measure-time",
.arg = G_OPTION_ARG_INT,
.arg_data = &measure_time,
.description = "Duration of automated tests in ms",
},
{
.long_name = "repeats",
.arg = G_OPTION_ARG_INT,
.arg_data = &repeats,
.description = "Number of times to repeat automated test",
},
{
.long_name = "cpu-freq",
.arg = G_OPTION_ARG_NONE,
.arg_data = &cpu_freq,
.description = "Monitor CPU frequencies during automated test",
},
{
.long_name = "freq-granularity",
.arg = G_OPTION_ARG_INT,
.arg_data = &freq_granularity,
.description = "Granularity in ms for measuring CPU frequencies",
},
{ NULL, }
};

Expand All @@ -1525,6 +1572,8 @@ static void options(int *argc, char ***argv) {

if (max_cpu > 100 || max_cpu < 0)
die("Invalid `max-cpu` number given");
if (freq_granularity <= 0)
die("Invalid `freq-granularity` number given");
}


Expand Down Expand Up @@ -1582,6 +1631,63 @@ static void delay_measure_workers(uint milliseconds, struct stats *totals) {
}


static void *cpu_freq_monitor(void *p) {
struct thread_freq_stats *freq_stats = p;

while (true) {
struct freq_stats iter_stats = {0};

{
AUTO_CLEANUP(DIR *dp, closedir_p) = opendir("/sys/devices/system/cpu/cpufreq");
if (!dp)
break; // bail out


struct dirent *ent;
while ((ent = readdir(dp))) {
if (strncmp(ent->d_name, "policy", 6) != 0)
continue; // skip

AUTO_CLEANUP(char *fn, free_gbuf)
= g_strdup_printf("/sys/devices/system/cpu/cpufreq/%s/scaling_cur_freq",
ent->d_name);
AUTO_CLEANUP(FILE *fp, fclose_p) = fopen(fn, "r");
if (!fp)
continue; // ignore

long long freq;
int rets = fscanf(fp, "%lld", &freq);
if (rets != 1)
continue; // ignore

iter_stats.max = iter_stats.max ? MAX(iter_stats.max, freq) : freq;
iter_stats.min = iter_stats.min ? MIN(iter_stats.min, freq) : freq;
iter_stats.sum += freq;
iter_stats.samples++;
}
}

// done collecting, add to shared struct

{
LOCK(&freq_stats->lock);
freq_stats->stats.max = freq_stats->stats.max
? MAX(freq_stats->stats.max, iter_stats.max) : iter_stats.max;
freq_stats->stats.min = freq_stats->stats.min
? MIN(freq_stats->stats.min, iter_stats.min) : iter_stats.min;
freq_stats->stats.sum += iter_stats.sum;
freq_stats->stats.samples += iter_stats.samples;
}

thread_cancel_enable();
usleep(freq_granularity * 1000);
thread_cancel_disable();
}

return NULL;
}


static void max_cpu_test(void) {
int max_cpu_scaled = max_cpu * 100000;

Expand All @@ -1590,17 +1696,24 @@ static void max_cpu_test(void) {
uint test_num = 1;
set_streams(test_num);

while (true) {
pthread_t cpu_thread = 0;
struct thread_freq_stats freq_stats = {.lock = MUTEX_STATIC_INIT};
if (cpu_freq)
cpu_thread = thread_new("CPU freq", cpu_freq_monitor, &freq_stats);

int count = repeats;

while (count > 0) {
// initial break-in
delay_measure_workers(200, NULL);
delay_measure_workers(break_in, NULL);
cpu_collect(NULL, NULL);

// measure
struct stats totals = {0};
if (!system_cpu)
delay_measure_workers(500, &totals);
delay_measure_workers(measure_time, &totals);
else {
delay_measure_workers(500, NULL);
delay_measure_workers(measure_time, NULL);
cpu_collect(NULL, &totals);
}

Expand Down Expand Up @@ -1632,7 +1745,28 @@ static void max_cpu_test(void) {
? "bidirectional calls"
: "unidirectional streams",
workers.length);
break;

if (cpu_freq) {
// retrieve stats and reset
struct freq_stats stats;
{
LOCK(&freq_stats.lock);
stats = freq_stats.stats;
freq_stats.stats = (__typeof__(freq_stats.stats)) {0};
}
if (!stats.samples)
printf(" (no CPU frequency stats collected)\n");
else {
printf(" CPU frequencies: "
"%.2f <> %.2f GHz, avg %.2f GHz\n",
(float) stats.min / 1000000.,
(float) stats.max / 1000000.,
(float) stats.sum / (float) stats.samples
/ 1000000.);
}
}

count--;
}

// scale to 50..100
Expand All @@ -1643,6 +1777,11 @@ static void max_cpu_test(void) {

set_streams(test_num);
}

if (cpu_thread) {
pthread_cancel(cpu_thread);
pthread_join(cpu_thread, NULL);
}
}


Expand Down

0 comments on commit 2aa8520

Please sign in to comment.