Compare commits

..

3 Commits

Author SHA1 Message Date
7ce7101240 Add page fault stats to repetition tester 2023-09-23 23:55:46 +01:00
dca94a0edf Restructure of repetition tester 2023-09-23 23:06:38 +01:00
b7d33de2d7 Update comment 2023-09-23 22:44:13 +01:00
3 changed files with 150 additions and 28 deletions

View File

@ -13,6 +13,22 @@ struct reptest_params {
struct reptest_results {
u64 bytes_read;
u64 read_time;
u64 page_faults;
};
struct time_stats {
u64 min_time;
u64 max_time;
u64 avg_time;
u64 total_time;
};
struct mem_stats {
u64 min_faults;
u64 max_faults;
u64 avg_faults;
u64 total_bytes;
u64 total_faults;
};
struct reptester {
@ -25,10 +41,8 @@ struct reptester {
u64 test_start_time;
u64 current_run;
u64 min;
u64 max;
u64 avg;
u64 total;
time_stats tstats;
mem_stats mstats;
reptest_results results;
};
@ -51,6 +65,7 @@ void handle_alloc(reptester *tester, alloc_type type);
void handle_free(reptester *tester, alloc_type type);
void run_func_test(reptester *tester, reptest_func func, const char *func_name,
alloc_type type);
u64 page_fault_count();
void print_results(reptester *tester, const char *name);
#endif // !REPTESTER_H

View File

@ -11,6 +11,7 @@
void test_fread(reptester *tester, alloc_type type);
void test_read(reptester *tester, alloc_type type);
void test_write(reptester *tester, alloc_type type);
u64 get_file_length(FILE *fp);
int main(int argc, char *argv[]) {
@ -20,7 +21,7 @@ int main(int argc, char *argv[]) {
switch (argc) {
case 3:
waves = atol(argv[2]);
// break left intentionally
// break left out intentionally
case 2:
filename = argv[1];
break;
@ -40,10 +41,19 @@ int main(int argc, char *argv[]) {
read_cpu_timer(), // test_start_time
1, // current_run
UINT64_MAX, // min
0, // max
0, // avg
0, // total
{
UINT64_MAX, // min_time
0, // max_time
0, // avg_time
0, // total_time
},
{
0, // min_faults
0, // max_faults
0, // avg_faults
0, // total_bytes
0, // total_faults
},
{}, // results
};
// clang-format on
@ -53,7 +63,8 @@ int main(int argc, char *argv[]) {
return -1;
}
func_data funcs[] = {{{"READ", "READ WITH MALLOC"}, test_read},
func_data funcs[] = {{{"WRITE", "WRITE WITH MALLOC"}, test_write},
{{"READ", "READ WITH MALLOC"}, test_read},
{{"FREAD", "FREAD WITH MALLOC"}, test_fread}};
tester.params.read_size = get_file_length(fp);
@ -85,17 +96,23 @@ void test_fread(reptester *tester, alloc_type type) {
handle_alloc(tester, type);
u64 start = read_cpu_timer();
u64 fault_count_start = page_fault_count();
u64 obj_count = fread(tester->params.buffer, tester->params.read_size,
tester->params.read_count, fp);
u64 fault_count_end = page_fault_count();
u64 end = read_cpu_timer();
u64 bytes_read = obj_count * tester->params.read_size;
u64 read_time = end - start;
u64 page_faults = fault_count_end - fault_count_start;
tester->results = {
bytes_read,
read_time,
page_faults,
};
handle_free(tester, type);
@ -114,15 +131,21 @@ void test_read(reptester *tester, alloc_type type) {
i32 fd = fileno(fp);
u64 start = read_cpu_timer();
u64 fault_count_start = page_fault_count();
u64 bytes_read = read(fd, tester->params.buffer,
tester->params.read_size * tester->params.read_count);
u64 fault_count_end = page_fault_count();
u64 end = read_cpu_timer();
u64 read_time = end - start;
u64 page_faults = fault_count_end - fault_count_start;
tester->results = {
bytes_read,
read_time,
page_faults,
};
handle_free(tester, type);
@ -130,6 +153,33 @@ void test_read(reptester *tester, alloc_type type) {
fclose(fp);
}
void test_write(reptester *tester, alloc_type type) {
handle_alloc(tester, type);
u64 start = read_cpu_timer();
u64 fault_count_start = page_fault_count();
u64 total_size = tester->params.read_size * tester->params.read_count;
for (u64 i = 0; i < total_size; ++i) {
tester->params.buffer[i] = '0';
}
u64 fault_count_end = page_fault_count();
u64 end = read_cpu_timer();
u64 read_time = end - start;
u64 page_faults = fault_count_end - fault_count_start;
tester->results = {
total_size,
read_time,
page_faults,
};
handle_free(tester, type);
}
u64 get_file_length(FILE *fp) {
if (!fp) {
return 0;

View File

@ -3,6 +3,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
void handle_alloc(reptester *tester, alloc_type type) {
switch (type) {
@ -37,10 +39,19 @@ void run_func_test(reptester *tester, reptest_func func, const char *func_name,
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->tstats = {
UINT64_MAX, // min_time
0, // max_time
0, // avg_time
0, // total_time
};
tester->mstats = {
UINT64_MAX, // min_faults
0, // max_faults
0, // avg_faults
0, // total_bytes
0, // total_faults
};
tester->results = {};
char *buffer = NULL;
@ -63,13 +74,23 @@ void run_func_test(reptester *tester, reptest_func func, const char *func_name,
return;
}
tester->total += tester->results.read_time;
tester->tstats.total_time += tester->results.read_time;
tester->mstats.total_bytes += tester->results.bytes_read;
tester->mstats.total_faults += tester->results.page_faults;
if (tester->results.read_time > tester->max) {
tester->max = tester->results.read_time;
} else if (tester->results.read_time < tester->min) {
if (tester->results.read_time > tester->tstats.max_time) {
tester->tstats.max_time = tester->results.read_time;
tester->mstats.max_faults = tester->results.page_faults;
} else if (tester->results.read_time < tester->tstats.min_time) {
tester->test_start_time = read_cpu_timer();
tester->min = tester->results.read_time;
tester->tstats.min_time = tester->results.read_time;
tester->mstats.min_faults = tester->results.page_faults;
}
if (tester->results.page_faults > tester->mstats.max_faults) {
tester->mstats.max_faults = tester->results.page_faults;
} else if (tester->results.page_faults < tester->mstats.min_faults) {
tester->mstats.min_faults = tester->results.page_faults;
}
tester->test_time_secs = time_in_seconds(
@ -86,21 +107,57 @@ void run_func_test(reptester *tester, reptest_func func, const char *func_name,
print_results(tester, func_name);
}
void print_results(reptester *tester, const char *name) {
f64 gb = 1024.0 * 1024.0 * 1024.0;
u64 page_fault_count() {
rusage usage;
getrusage(RUSAGE_SELF, &usage);
return usage.ru_minflt + usage.ru_majflt;
}
void print_results(reptester *tester, const char *name) {
f64 kb = 1024.0;
f64 gb = kb * kb * kb;
f64 size_in_kb =
(f64)(tester->params.read_size * tester->params.read_count) / kb;
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;
tester->tstats.avg_time = tester->tstats.total_time / run_count;
tester->mstats.avg_faults = tester->mstats.total_faults / 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));
printf("MIN: %lu (%fGB/s)", tester->tstats.min_time,
size_in_gb /
time_in_seconds(tester->tstats.min_time, tester->cpu_freq));
if (tester->mstats.min_faults > 0) {
printf(", FAULTS: %lu (%fK/fault)\n", tester->mstats.min_faults,
size_in_kb / tester->mstats.min_faults);
} else {
printf("\n");
}
printf("MAX: %lu (%fGB/s)", tester->tstats.max_time,
size_in_gb /
time_in_seconds(tester->tstats.max_time, tester->cpu_freq));
if (tester->mstats.max_faults > 0) {
printf(", FAULTS: %lu (%fK/fault)\n", tester->mstats.max_faults,
size_in_kb / tester->mstats.max_faults);
} else {
printf("\n");
}
printf("AVG: %lu (%fGB/s)", tester->tstats.avg_time,
size_in_gb /
time_in_seconds(tester->tstats.avg_time, tester->cpu_freq));
if (tester->mstats.avg_faults > 0) {
printf(", FAULTS: %lu (%fK/fault)\n", tester->mstats.avg_faults,
tester->mstats.total_bytes / kb / tester->mstats.avg_faults);
} else {
printf("\n");
}
}