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

View File

@ -1,5 +1,6 @@
#include <inttypes.h>
#include <string.h>
#include <sys/resource.h>
#include "rprof.h"
enum tester_state {
@ -23,6 +24,7 @@ struct repetition_tester {
uint64_t test_running_time;
uint64_t test_running_bytes;
uint64_t test_running_page_faults;
};
struct repetition_results {
@ -30,6 +32,10 @@ struct repetition_results {
uint64_t total_time;
uint64_t min_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);
@ -44,7 +50,7 @@ void repetition_tester_error(struct repetition_tester *tester, char *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);
if (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);
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) {
@ -88,15 +110,20 @@ bool repetition_tester_continue(struct repetition_tester *tester, struct repetit
if (tester->show_current_min) {
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);
}
}
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->closed_blocks = 0;
tester->test_running_bytes = 0;
tester->test_running_time = 0;
tester->test_running_page_faults = 0;
uint64_t time_since_last_find = (now - tester->last_found_min_time);
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->test_count = 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)) {
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) {
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");
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");
if (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");
}
}
@ -150,11 +181,13 @@ void print_repetition_results(struct repetition_tester *tester, struct repetitio
void repetition_time_start(struct repetition_tester *tester) {
tester->opened_blocks++;
tester->test_running_time -= rprof_read_cpu_timer();
tester->test_running_page_faults -= read_page_faults();
}
void repetition_time_end(struct repetition_tester *tester) {
tester->closed_blocks++;
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) {

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