integrate measuring page faults to tester
This commit is contained in:
parent
21d0b292cc
commit
a7d0e49ab9
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
||||
CFLAGS=-lm -g -Wall -O2
|
||||
CFLAGS=-lm -g -Wall -O3 -mavx2
|
||||
|
||||
.PHONY := gen_data main
|
||||
|
||||
|
@ -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) {
|
||||
|
31
src/tests.c
31
src/tests.c
@ -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, ¶ms)) {
|
||||
return -1;
|
||||
}
|
||||
@ -147,5 +166,7 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
printf("page faults: %lu\n", read_page_faults());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user