Basic repetition testing implementation
This commit is contained in:
parent
1bfc162845
commit
9ddb991b94
44
haversine_02/include/repetition_testing/reptester.h
Normal file
44
haversine_02/include/repetition_testing/reptester.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef REPTESTER_H
|
||||||
|
#define REPTESTER_H
|
||||||
|
|
||||||
|
#include "aliases.h"
|
||||||
|
|
||||||
|
struct reptest_params {
|
||||||
|
const char *filename;
|
||||||
|
char *buffer;
|
||||||
|
u64 read_size;
|
||||||
|
u64 read_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reptest_results {
|
||||||
|
u64 bytes_read;
|
||||||
|
u64 read_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reptester {
|
||||||
|
reptest_params params;
|
||||||
|
|
||||||
|
const u64 cpu_freq;
|
||||||
|
|
||||||
|
f64 wait_time_secs;
|
||||||
|
f64 test_time_secs;
|
||||||
|
u64 test_start_time;
|
||||||
|
|
||||||
|
u64 current_run;
|
||||||
|
u64 min;
|
||||||
|
u64 max;
|
||||||
|
u64 avg;
|
||||||
|
u64 total;
|
||||||
|
|
||||||
|
reptest_results results;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reptest_func {
|
||||||
|
const char *name;
|
||||||
|
void (*func)(reptester *tester);
|
||||||
|
};
|
||||||
|
|
||||||
|
void run_func_test(reptester *tester, reptest_func func_obj);
|
||||||
|
void print_results(reptester *tester, const char *name);
|
||||||
|
|
||||||
|
#endif // !REPTESTER_H
|
134
haversine_02/src/repetition_testing/main.cpp
Normal file
134
haversine_02/src/repetition_testing/main.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "aliases.h"
|
||||||
|
#include "profiler/timer.h"
|
||||||
|
#include "repetition_testing/reptester.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define ARR_LEN(ARR) sizeof(ARR) / sizeof(*ARR)
|
||||||
|
|
||||||
|
void test_fread(reptester *tester);
|
||||||
|
void test_read(reptester *tester);
|
||||||
|
u64 get_file_length(FILE *fp);
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char *filename = NULL;
|
||||||
|
u64 waves = 1;
|
||||||
|
|
||||||
|
switch (argc) {
|
||||||
|
case 3:
|
||||||
|
waves = atol(argv[2]);
|
||||||
|
// break left intentionally
|
||||||
|
case 2:
|
||||||
|
filename = argv[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Usage: reptest FILENAME [WAVE_COUNT]\n");
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
reptester tester = {
|
||||||
|
{filename, NULL, 0, 0}, // params
|
||||||
|
get_cpu_freq(500), // cpu_freq
|
||||||
|
|
||||||
|
10.0, // wait_time_secs
|
||||||
|
0.0, // test_time_secs
|
||||||
|
read_cpu_timer(), // test_start_time
|
||||||
|
|
||||||
|
1, // current_run
|
||||||
|
UINT64_MAX, // min
|
||||||
|
0, // max
|
||||||
|
0, // avg
|
||||||
|
0, // total
|
||||||
|
{}, // results
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
FILE *fp = fopen(tester.params.filename, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
reptest_func funcs[] = {{"FREAD", test_fread}, {"READ", test_read}};
|
||||||
|
|
||||||
|
tester.params.read_size = get_file_length(fp);
|
||||||
|
tester.params.read_count = 1;
|
||||||
|
tester.params.buffer = (char *)malloc(tester.params.read_size + 1);
|
||||||
|
memset(tester.params.buffer, 0, tester.params.read_size + 1);
|
||||||
|
|
||||||
|
for (u64 i = 0; i < waves; ++i) {
|
||||||
|
for (u64 j = 0; j < ARR_LEN(funcs); ++j) {
|
||||||
|
run_func_test(&tester, funcs[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
free(tester.params.buffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_fread(reptester *tester) {
|
||||||
|
FILE *fp = fopen(tester->params.filename, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 start = read_cpu_timer();
|
||||||
|
u64 obj_count = fread(tester->params.buffer, tester->params.read_size,
|
||||||
|
tester->params.read_count, fp);
|
||||||
|
u64 end = read_cpu_timer();
|
||||||
|
|
||||||
|
u64 bytes_read = obj_count * tester->params.read_size;
|
||||||
|
|
||||||
|
u64 read_time = end - start;
|
||||||
|
|
||||||
|
tester->results = {
|
||||||
|
bytes_read,
|
||||||
|
read_time,
|
||||||
|
};
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_read(reptester *tester) {
|
||||||
|
FILE *fp = fopen(tester->params.filename, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 fd = fileno(fp);
|
||||||
|
|
||||||
|
u64 start = read_cpu_timer();
|
||||||
|
u64 bytes_read = read(fd, tester->params.buffer,
|
||||||
|
tester->params.read_size * tester->params.read_count);
|
||||||
|
u64 end = read_cpu_timer();
|
||||||
|
|
||||||
|
u64 read_time = end - start;
|
||||||
|
|
||||||
|
tester->results = {
|
||||||
|
bytes_read,
|
||||||
|
read_time,
|
||||||
|
};
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 get_file_length(FILE *fp) {
|
||||||
|
if (!fp) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
|
||||||
|
u64 length = ftell(fp);
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
62
haversine_02/src/repetition_testing/reptester.cpp
Normal file
62
haversine_02/src/repetition_testing/reptester.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include "repetition_testing/reptester.h"
|
||||||
|
#include "profiler/timer.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void run_func_test(reptester *tester, reptest_func func_obj) {
|
||||||
|
tester->test_start_time = read_cpu_timer();
|
||||||
|
tester->test_time_secs = 0.0;
|
||||||
|
tester->current_run = 1;
|
||||||
|
tester->min = UINT64_MAX;
|
||||||
|
tester->max = 0;
|
||||||
|
tester->avg = 0;
|
||||||
|
tester->total = 0;
|
||||||
|
tester->results = {};
|
||||||
|
|
||||||
|
while (tester->test_time_secs <= tester->wait_time_secs) {
|
||||||
|
func_obj.func(tester);
|
||||||
|
|
||||||
|
if (tester->results.bytes_read <
|
||||||
|
tester->params.read_size * tester->params.read_count) {
|
||||||
|
printf("Failed to read the entire file (Total size: %lu, Bytes read: "
|
||||||
|
"%lu)\n",
|
||||||
|
tester->params.read_size, tester->results.bytes_read);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tester->total += tester->results.read_time;
|
||||||
|
|
||||||
|
if (tester->results.read_time > tester->max) {
|
||||||
|
tester->max = tester->results.read_time;
|
||||||
|
} else if (tester->results.read_time < tester->min) {
|
||||||
|
tester->test_start_time = read_cpu_timer();
|
||||||
|
tester->min = tester->results.read_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
tester->test_time_secs = time_in_seconds(
|
||||||
|
read_cpu_timer() - tester->test_start_time, tester->cpu_freq);
|
||||||
|
|
||||||
|
++(tester->current_run);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_results(tester, func_obj.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_results(reptester *tester, const char *name) {
|
||||||
|
f64 gb = 1024.0 * 1024.0 * 1024.0;
|
||||||
|
|
||||||
|
f64 size_in_gb =
|
||||||
|
(f64)(tester->params.read_size * tester->params.read_count) / gb;
|
||||||
|
|
||||||
|
u64 run_count = tester->current_run - 1;
|
||||||
|
|
||||||
|
tester->avg = tester->total / run_count;
|
||||||
|
|
||||||
|
printf("\n%s: %lu runs\n", name, run_count);
|
||||||
|
printf("MIN: %lu (%fGB/s)\n", tester->min,
|
||||||
|
size_in_gb / time_in_seconds(tester->min, tester->cpu_freq));
|
||||||
|
printf("MAX: %lu (%fGB/s)\n", tester->max,
|
||||||
|
size_in_gb / time_in_seconds(tester->max, tester->cpu_freq));
|
||||||
|
printf("AVG: %lu (%fGB/s)\n", tester->avg,
|
||||||
|
size_in_gb / time_in_seconds(tester->avg, tester->cpu_freq));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user