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
|
.PHONY := gen_data main
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
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)
|
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, ¶ms)) {
|
if (repetition_test_run(&tester, file_size, &results, testcase->cb, ¶ms)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -147,5 +166,7 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("page faults: %lu\n", read_page_faults());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user