Add page fault stats to repetition tester
This commit is contained in:
		@@ -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[]) {
 | 
			
		||||
@@ -41,10 +42,17 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
 | 
			
		||||
      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
 | 
			
		||||
  };
 | 
			
		||||
@@ -55,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);
 | 
			
		||||
@@ -87,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);
 | 
			
		||||
@@ -116,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);
 | 
			
		||||
@@ -132,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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
@@ -43,6 +45,13 @@ void run_func_test(reptester *tester, reptest_func func, const char *func_name,
 | 
			
		||||
      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;
 | 
			
		||||
@@ -66,12 +75,22 @@ void run_func_test(reptester *tester, reptest_func func, const char *func_name,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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->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->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(
 | 
			
		||||
@@ -88,24 +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->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->tstats.min_time,
 | 
			
		||||
 | 
			
		||||
  printf("MIN: %lu (%fGB/s)", tester->tstats.min_time,
 | 
			
		||||
         size_in_gb /
 | 
			
		||||
             time_in_seconds(tester->tstats.min_time, tester->cpu_freq));
 | 
			
		||||
  printf("MAX: %lu (%fGB/s)\n", tester->tstats.max_time,
 | 
			
		||||
  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));
 | 
			
		||||
  printf("AVG: %lu (%fGB/s)\n", tester->tstats.avg_time,
 | 
			
		||||
  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");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user