Compare commits

..

5 Commits

Author SHA1 Message Date
4b905a56a5 Update .gitignore 2023-09-09 21:26:45 +01:00
967b1524d7 Update compile script 2023-09-09 21:26:35 +01:00
ab99d4b003 Update parser.c 2023-09-09 21:26:22 +01:00
22466ea56f Add time_in_seconds function 2023-09-09 21:25:57 +01:00
9ddb991b94 Basic repetition testing implementation 2023-09-09 21:25:32 +01:00
8 changed files with 263 additions and 8 deletions

View File

@ -5,4 +5,5 @@ pairs.json
main main
genhavr genhavr
prochavr prochavr
reptest
timer_test* timer_test*

View File

@ -47,7 +47,6 @@ GENOUT=genhavr
(set -x ; $CXX $CFLAGS $GENSRC -o $GENOUT) (set -x ; $CXX $CFLAGS $GENSRC -o $GENOUT)
echo echo
# PROFILER # PROFILER
PROFSRC="../src/profiler/timer.c" PROFSRC="../src/profiler/timer.c"
PROFFLAGS="-c " PROFFLAGS="-c "
@ -69,10 +68,12 @@ if [[ $BASIC_PROFILING == true ]] || [[ $FULL_PROFILING == true ]]; then
if [[ $FULL_PROFILING == true ]]; then if [[ $FULL_PROFILING == true ]]; then
JSONFLAGS+="-DFULL_PROFILING" JSONFLAGS+="-DFULL_PROFILING"
PROCFLAGS="-DFULL_PROFILING" PROCFLAGS="-DFULL_PROFILING"
REPTESTFLAGS="-DFULL_PROFILING"
PROFFLAGS+="-DFULL_PROFILING" PROFFLAGS+="-DFULL_PROFILING"
elif [[ $BASIC_PROFILING == true ]]; then elif [[ $BASIC_PROFILING == true ]]; then
JSONFLAGS+="-DBASIC_PROFILING" JSONFLAGS+="-DBASIC_PROFILING"
PROCFLAGS="-DBASIC_PROFILING" PROCFLAGS="-DBASIC_PROFILING"
REPTESTFLAGS="-DBASIC_PROFILING"
PROFFLAGS+="-DBASIC_PROFILING" PROFFLAGS+="-DBASIC_PROFILING"
fi fi
@ -85,6 +86,13 @@ if [[ $BASIC_PROFILING == true ]] || [[ $FULL_PROFILING == true ]]; then
echo echo
cd ../ cd ../
# REPETITION TESTING
REPTESTSRC="./src/repetition_testing/*.cpp ./$PROF_BUILD_DIR/*.o"
REPTESTOUT=reptest
(set -x ; $CC $CFLAGS $REPTESTFLAGS $REPTESTSRC -o $REPTESTOUT)
echo
fi fi
mkdir $JSON_BUILD_DIR mkdir $JSON_BUILD_DIR
@ -98,6 +106,5 @@ cd ../
(set -x ; $CXX $CFLAGS $PROCFLAGS $PROCSRC -o $PROCOUT) (set -x ; $CXX $CFLAGS $PROCFLAGS $PROCSRC -o $PROCOUT)
echo echo
# CLEAR BUILD FILES # CLEAR BUILD FILES
rm -rvf $JSON_BUILD_DIR $PROF_BUILD_DIR rm -rvf $JSON_BUILD_DIR $PROF_BUILD_DIR

View File

@ -61,6 +61,8 @@ u64 read_cpu_timer(void);
// CPU frequency in hz/sec // CPU frequency in hz/sec
u64 get_cpu_freq(u64 milliseconds); u64 get_cpu_freq(u64 milliseconds);
f64 time_in_seconds(u64 cpu_time, u64 cpu_freq);
void profile_start(u64 count); void profile_start(u64 count);
void profile_end(); void profile_end();

View 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

View File

@ -23,8 +23,6 @@ INTERNAL jentity_t *add_value(parser_t *parser);
INTERNAL void add_collection(parser_t *parser); INTERNAL void add_collection(parser_t *parser);
jentity_t *load_json(const char *filepath) { jentity_t *load_json(const char *filepath) {
SAMPLE_START(PROFILER_ID_READ_JSON_FILE, "READ JSON FILE");
FILE *fp = fopen(filepath, "r"); FILE *fp = fopen(filepath, "r");
if (!fp) { if (!fp) {
@ -40,12 +38,14 @@ jentity_t *load_json(const char *filepath) {
char *json = (char *)malloc(sizeof(char) * (length + 1)); char *json = (char *)malloc(sizeof(char) * (length + 1));
memset(json, 0, length + 1); memset(json, 0, length + 1);
SAMPLE_START(PROFILER_ID_READ_JSON_FILE, "READ JSON FILE");
fread(json, sizeof(char), length, fp); fread(json, sizeof(char), length, fp);
fclose(fp);
SAMPLE_END(PROFILER_ID_READ_JSON_FILE, length); SAMPLE_END(PROFILER_ID_READ_JSON_FILE, length);
fclose(fp);
SAMPLE_START(PROFILER_ID_PARSER_SETUP, "JSON PARSER SETUP"); SAMPLE_START(PROFILER_ID_PARSER_SETUP, "JSON PARSER SETUP");
lexer_t *lexer = NULL; lexer_t *lexer = NULL;

View File

@ -38,12 +38,13 @@ u64 read_cpu_timer(void) { return __rdtsc(); }
u64 get_cpu_freq(u64 milliseconds) { u64 get_cpu_freq(u64 milliseconds) {
u64 os_freq = get_os_frequency(); u64 os_freq = get_os_frequency();
u64 os_start = get_os_time();
u64 cpu_start = read_cpu_timer();
u64 os_end = 0; u64 os_end = 0;
u64 os_elapsed = 0; u64 os_elapsed = 0;
u64 os_wait_time = os_freq * milliseconds / 1000; u64 os_wait_time = os_freq * milliseconds / 1000;
u64 os_start = get_os_time();
u64 cpu_start = read_cpu_timer();
while (os_elapsed < os_wait_time) { while (os_elapsed < os_wait_time) {
os_end = get_os_time(); os_end = get_os_time();
os_elapsed = os_end - os_start; os_elapsed = os_end - os_start;
@ -61,6 +62,10 @@ u64 get_cpu_freq(u64 milliseconds) {
return cpu_freq; return cpu_freq;
} }
f64 time_in_seconds(u64 cpu_time, u64 cpu_freq) {
return (f64)cpu_time / cpu_freq;
}
void profile_start(u64 count) { void profile_start(u64 count) {
profiler.cpu_freq = get_cpu_freq(1000); profiler.cpu_freq = get_cpu_freq(1000);
profiler.start = read_cpu_timer(); profiler.start = read_cpu_timer();

View 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;
}

View 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));
}