1
0

integrate measuring page faults to tester

This commit is contained in:
Rokas Puzonas 2023-09-11 23:20:12 +03:00
parent 21d0b292cc
commit a7d0e49ab9
3 changed files with 65 additions and 11 deletions

View File

@ -1,4 +1,4 @@
CFLAGS=-lm -g -Wall -O2 CFLAGS=-lm -g -Wall -O3 -mavx2
.PHONY := gen_data main .PHONY := gen_data main

View File

@ -1,5 +1,6 @@
#include <inttypes.h> #include <inttypes.h>
#include <string.h> #include <string.h>
#include <sys/resource.h>
#include "rprof.h" #include "rprof.h"
enum tester_state { enum tester_state {
@ -23,6 +24,7 @@ struct repetition_tester {
uint64_t test_running_time; uint64_t test_running_time;
uint64_t test_running_bytes; uint64_t test_running_bytes;
uint64_t test_running_page_faults;
}; };
struct repetition_results { struct repetition_results {
@ -30,6 +32,10 @@ struct repetition_results {
uint64_t total_time; uint64_t total_time;
uint64_t min_time; uint64_t min_time;
uint64_t max_time; uint64_t max_time;
uint64_t total_page_faults;
uint64_t min_page_faults;
uint64_t max_page_faults;
}; };
typedef void (*test_cb)(struct repetition_tester*, void *user); typedef void (*test_cb)(struct repetition_tester*, void *user);
@ -44,7 +50,7 @@ void repetition_tester_error(struct repetition_tester *tester, char *message) {
printf("Error during repetition: %s\n", message); printf("Error during repetition: %s\n", message);
} }
void print_repetition_time(char *label, float cpu_time, uint64_t bytes, uint64_t cpu_freq) { void print_repetition_time(char *label, float cpu_time, uint64_t bytes, uint64_t page_faults, uint64_t cpu_freq) {
printf("%s: %.0f", label, cpu_time); printf("%s: %.0f", label, cpu_time);
if (cpu_freq) { if (cpu_freq) {
float seconds_time = (float)cpu_time/(float)cpu_freq; float seconds_time = (float)cpu_time/(float)cpu_freq;
@ -55,7 +61,23 @@ void print_repetition_time(char *label, float cpu_time, uint64_t bytes, uint64_t
float bandwidth = bytes / (gigabyte * seconds_time); float bandwidth = bytes / (gigabyte * seconds_time);
printf(" at %fgb/s", bandwidth); printf(" at %fgb/s", bandwidth);
} }
} }
if (page_faults) {
printf(" PF: %lu", page_faults);
if (bytes) {
printf(" (%.3fkb/fault)", ((float)bytes)/(page_faults * 1024));
}
}
}
uint64_t read_page_faults() {
// NOTE: ru_minflt the number of page faults serviced without any I/O activity.
// ru_majflt the number of page faults serviced that required I/O activity.
struct rusage usage = {};
getrusage(RUSAGE_SELF, &usage);
int Result = usage.ru_minflt + usage.ru_majflt;
return Result;
} }
bool repetition_tester_continue(struct repetition_tester *tester, struct repetition_results *results) { bool repetition_tester_continue(struct repetition_tester *tester, struct repetition_results *results) {
@ -88,15 +110,20 @@ bool repetition_tester_continue(struct repetition_tester *tester, struct repetit
if (tester->show_current_min) { if (tester->show_current_min) {
printf("\r"); printf("\r");
print_repetition_time("Min", tester->test_running_time, tester->test_running_bytes, tester->cpu_freq); print_repetition_time("Min", tester->test_running_time, tester->test_running_bytes, 0, tester->cpu_freq);
fflush(stdout); fflush(stdout);
} }
} }
results->total_page_faults += tester->test_running_page_faults;
results->min_page_faults = MIN(results->min_page_faults, tester->test_running_page_faults);
results->max_page_faults = MAX(results->max_page_faults, tester->test_running_page_faults);
tester->opened_blocks = 0; tester->opened_blocks = 0;
tester->closed_blocks = 0; tester->closed_blocks = 0;
tester->test_running_bytes = 0; tester->test_running_bytes = 0;
tester->test_running_time = 0; tester->test_running_time = 0;
tester->test_running_page_faults = 0;
uint64_t time_since_last_find = (now - tester->last_found_min_time); uint64_t time_since_last_find = (now - tester->last_found_min_time);
if ((time_since_last_find / tester->cpu_freq) >= tester->testing_timeout) { if ((time_since_last_find / tester->cpu_freq) >= tester->testing_timeout) {
@ -117,6 +144,9 @@ int repetition_test_run(struct repetition_tester *tester, uint64_t expected_byte
results->max_time = 0; results->max_time = 0;
results->test_count = 0; results->test_count = 0;
results->total_time = 0; results->total_time = 0;
results->max_page_faults = 0;
results->min_page_faults = UINT64_MAX;
results->total_page_faults = 0;
while (repetition_tester_continue(tester, results)) { while (repetition_tester_continue(tester, results)) {
cb(tester, user); cb(tester, user);
@ -134,15 +164,16 @@ int repetition_test_run(struct repetition_tester *tester, uint64_t expected_byte
} }
void print_repetition_results(struct repetition_tester *tester, struct repetition_results *results) { void print_repetition_results(struct repetition_tester *tester, struct repetition_results *results) {
print_repetition_time("Min", results->min_time, tester->expected_byte_count, tester->cpu_freq); print_repetition_time("Min", results->min_time, tester->expected_byte_count, results->min_page_faults, tester->cpu_freq);
printf("\n"); printf("\n");
print_repetition_time("Max", results->max_time, tester->expected_byte_count, tester->cpu_freq); print_repetition_time("Max", results->max_time, tester->expected_byte_count, results->max_page_faults, tester->cpu_freq);
printf("\n"); printf("\n");
if (results->test_count) { if (results->test_count) {
uint64_t avg_time = results->total_time/results->test_count; uint64_t avg_time = results->total_time/results->test_count;
print_repetition_time("Avg", avg_time, tester->expected_byte_count, tester->cpu_freq); uint64_t avg_page_faults = results->total_page_faults/results->test_count;
print_repetition_time("Avg", avg_time, tester->expected_byte_count, avg_page_faults, tester->cpu_freq);
printf("\n"); printf("\n");
} }
} }
@ -150,11 +181,13 @@ void print_repetition_results(struct repetition_tester *tester, struct repetitio
void repetition_time_start(struct repetition_tester *tester) { void repetition_time_start(struct repetition_tester *tester) {
tester->opened_blocks++; tester->opened_blocks++;
tester->test_running_time -= rprof_read_cpu_timer(); tester->test_running_time -= rprof_read_cpu_timer();
tester->test_running_page_faults -= read_page_faults();
} }
void repetition_time_end(struct repetition_tester *tester) { void repetition_time_end(struct repetition_tester *tester) {
tester->closed_blocks++; tester->closed_blocks++;
tester->test_running_time += rprof_read_cpu_timer(); tester->test_running_time += rprof_read_cpu_timer();
tester->test_running_page_faults += read_page_faults();
} }
void repetition_count_bytes(struct repetition_tester *tester, int bytes) { void repetition_count_bytes(struct repetition_tester *tester, int bytes) {

View File

@ -47,6 +47,23 @@ void handle_buffer_free(struct test_params *params) {
} }
} }
void test_write_bytes(struct repetition_tester *tester, void *user)
{
struct test_params *params = user;
handle_buffer_malloc(params);
repetition_time_start(tester);
for (uint64_t i = 0; i < params->byte_count; ++i) {
params->buffer[i] = (uint8_t)i;
}
repetition_time_end(tester);
repetition_count_bytes(tester, params->byte_count);
handle_buffer_free(params);
}
void test_fread(struct repetition_tester *tester, void *user) void test_fread(struct repetition_tester *tester, void *user)
{ {
struct test_params *params = user; struct test_params *params = user;
@ -108,12 +125,15 @@ int main()
char *filename = "data_10000000.json"; char *filename = "data_10000000.json";
uint64_t file_size = get_file_size(filename); uint64_t file_size = get_file_size(filename);
printf("File size: %lu\n", file_size);
struct testcase cases[] = { struct testcase cases[] = {
{ .name = "read inner malloc", .cb = test_read, .inner_malloc = true }, { .name = "write bytes", .cb = test_write_bytes, .inner_malloc = false },
{ .name = "read outer malloc", .cb = test_read, .inner_malloc = false }, { .name = "write bytes + malloc", .cb = test_write_bytes, .inner_malloc = true },
{ .name = "fread inner malloc", .cb = test_fread, .inner_malloc = true }, { .name = "read", .cb = test_read, .inner_malloc = false },
{ .name = "fread outer malloc", .cb = test_fread, .inner_malloc = false }, { .name = "read + malloc", .cb = test_read, .inner_malloc = true },
{ .name = "fread", .cb = test_fread, .inner_malloc = false },
{ .name = "fread + malloc", .cb = test_fread, .inner_malloc = true },
}; };
struct repetition_results results = { 0 }; struct repetition_results results = { 0 };
@ -133,7 +153,6 @@ int main()
.inner_malloc = testcase->inner_malloc .inner_malloc = testcase->inner_malloc
}; };
if (repetition_test_run(&tester, file_size, &results, testcase->cb, &params)) { if (repetition_test_run(&tester, file_size, &results, testcase->cb, &params)) {
return -1; return -1;
} }
@ -147,5 +166,7 @@ int main()
} }
} }
printf("page faults: %lu\n", read_page_faults());
return 0; return 0;
} }