Basic repetition testing implementation
This commit is contained in:
		
							
								
								
									
										134
									
								
								haversine_02/src/repetition_testing/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								haversine_02/src/repetition_testing/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
#include "aliases.h"
 | 
			
		||||
#include "profiler/timer.h"
 | 
			
		||||
#include "repetition_testing/reptester.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#define ARR_LEN(ARR) sizeof(ARR) / sizeof(*ARR)
 | 
			
		||||
 | 
			
		||||
void test_fread(reptester *tester);
 | 
			
		||||
void test_read(reptester *tester);
 | 
			
		||||
u64 get_file_length(FILE *fp);
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]) {
 | 
			
		||||
  const char *filename = NULL;
 | 
			
		||||
  u64 waves = 1;
 | 
			
		||||
 | 
			
		||||
  switch (argc) {
 | 
			
		||||
  case 3:
 | 
			
		||||
    waves = atol(argv[2]);
 | 
			
		||||
  // break left intentionally
 | 
			
		||||
  case 2:
 | 
			
		||||
    filename = argv[1];
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    printf("Usage: reptest FILENAME [WAVE_COUNT]\n");
 | 
			
		||||
    return -1;
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // clang-format off
 | 
			
		||||
  reptester tester = {
 | 
			
		||||
      {filename, NULL, 0, 0}, // params
 | 
			
		||||
      get_cpu_freq(500),          // cpu_freq
 | 
			
		||||
 | 
			
		||||
      10.0,                       // wait_time_secs
 | 
			
		||||
      0.0,                        // test_time_secs
 | 
			
		||||
      read_cpu_timer(),           // test_start_time
 | 
			
		||||
 | 
			
		||||
      1,                          // current_run
 | 
			
		||||
      UINT64_MAX,                 // min
 | 
			
		||||
      0,                          // max
 | 
			
		||||
		  0,                          // avg
 | 
			
		||||
      0,                          // total
 | 
			
		||||
		  {},                         // results
 | 
			
		||||
  };
 | 
			
		||||
  // clang-format on
 | 
			
		||||
 | 
			
		||||
  FILE *fp = fopen(tester.params.filename, "rb");
 | 
			
		||||
  if (!fp) {
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  reptest_func funcs[] = {{"FREAD", test_fread}, {"READ", test_read}};
 | 
			
		||||
 | 
			
		||||
  tester.params.read_size = get_file_length(fp);
 | 
			
		||||
  tester.params.read_count = 1;
 | 
			
		||||
  tester.params.buffer = (char *)malloc(tester.params.read_size + 1);
 | 
			
		||||
  memset(tester.params.buffer, 0, tester.params.read_size + 1);
 | 
			
		||||
 | 
			
		||||
  for (u64 i = 0; i < waves; ++i) {
 | 
			
		||||
    for (u64 j = 0; j < ARR_LEN(funcs); ++j) {
 | 
			
		||||
      run_func_test(&tester, funcs[j]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
 | 
			
		||||
  free(tester.params.buffer);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_fread(reptester *tester) {
 | 
			
		||||
  FILE *fp = fopen(tester->params.filename, "rb");
 | 
			
		||||
  if (!fp) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  u64 start = read_cpu_timer();
 | 
			
		||||
  u64 obj_count = fread(tester->params.buffer, tester->params.read_size,
 | 
			
		||||
                        tester->params.read_count, fp);
 | 
			
		||||
  u64 end = read_cpu_timer();
 | 
			
		||||
 | 
			
		||||
  u64 bytes_read = obj_count * tester->params.read_size;
 | 
			
		||||
 | 
			
		||||
  u64 read_time = end - start;
 | 
			
		||||
 | 
			
		||||
  tester->results = {
 | 
			
		||||
      bytes_read,
 | 
			
		||||
      read_time,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_read(reptester *tester) {
 | 
			
		||||
  FILE *fp = fopen(tester->params.filename, "rb");
 | 
			
		||||
  if (!fp) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  i32 fd = fileno(fp);
 | 
			
		||||
 | 
			
		||||
  u64 start = read_cpu_timer();
 | 
			
		||||
  u64 bytes_read = read(fd, tester->params.buffer,
 | 
			
		||||
                        tester->params.read_size * tester->params.read_count);
 | 
			
		||||
  u64 end = read_cpu_timer();
 | 
			
		||||
 | 
			
		||||
  u64 read_time = end - start;
 | 
			
		||||
 | 
			
		||||
  tester->results = {
 | 
			
		||||
      bytes_read,
 | 
			
		||||
      read_time,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u64 get_file_length(FILE *fp) {
 | 
			
		||||
  if (!fp) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fseek(fp, 0, SEEK_END);
 | 
			
		||||
 | 
			
		||||
  u64 length = ftell(fp);
 | 
			
		||||
 | 
			
		||||
  fseek(fp, 0, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
  return length;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								haversine_02/src/repetition_testing/reptester.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								haversine_02/src/repetition_testing/reptester.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#include "repetition_testing/reptester.h"
 | 
			
		||||
#include "profiler/timer.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
void run_func_test(reptester *tester, reptest_func func_obj) {
 | 
			
		||||
  tester->test_start_time = read_cpu_timer();
 | 
			
		||||
  tester->test_time_secs = 0.0;
 | 
			
		||||
  tester->current_run = 1;
 | 
			
		||||
  tester->min = UINT64_MAX;
 | 
			
		||||
  tester->max = 0;
 | 
			
		||||
  tester->avg = 0;
 | 
			
		||||
  tester->total = 0;
 | 
			
		||||
  tester->results = {};
 | 
			
		||||
 | 
			
		||||
  while (tester->test_time_secs <= tester->wait_time_secs) {
 | 
			
		||||
    func_obj.func(tester);
 | 
			
		||||
 | 
			
		||||
    if (tester->results.bytes_read <
 | 
			
		||||
        tester->params.read_size * tester->params.read_count) {
 | 
			
		||||
      printf("Failed to read the entire file (Total size: %lu, Bytes read: "
 | 
			
		||||
             "%lu)\n",
 | 
			
		||||
             tester->params.read_size, tester->results.bytes_read);
 | 
			
		||||
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tester->total += tester->results.read_time;
 | 
			
		||||
 | 
			
		||||
    if (tester->results.read_time > tester->max) {
 | 
			
		||||
      tester->max = tester->results.read_time;
 | 
			
		||||
    } else if (tester->results.read_time < tester->min) {
 | 
			
		||||
      tester->test_start_time = read_cpu_timer();
 | 
			
		||||
      tester->min = tester->results.read_time;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tester->test_time_secs = time_in_seconds(
 | 
			
		||||
        read_cpu_timer() - tester->test_start_time, tester->cpu_freq);
 | 
			
		||||
 | 
			
		||||
    ++(tester->current_run);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  print_results(tester, func_obj.name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_results(reptester *tester, const char *name) {
 | 
			
		||||
  f64 gb = 1024.0 * 1024.0 * 1024.0;
 | 
			
		||||
 | 
			
		||||
  f64 size_in_gb =
 | 
			
		||||
      (f64)(tester->params.read_size * tester->params.read_count) / gb;
 | 
			
		||||
 | 
			
		||||
  u64 run_count = tester->current_run - 1;
 | 
			
		||||
 | 
			
		||||
  tester->avg = tester->total / run_count;
 | 
			
		||||
 | 
			
		||||
  printf("\n%s: %lu runs\n", name, run_count);
 | 
			
		||||
  printf("MIN: %lu (%fGB/s)\n", tester->min,
 | 
			
		||||
         size_in_gb / time_in_seconds(tester->min, tester->cpu_freq));
 | 
			
		||||
  printf("MAX: %lu (%fGB/s)\n", tester->max,
 | 
			
		||||
         size_in_gb / time_in_seconds(tester->max, tester->cpu_freq));
 | 
			
		||||
  printf("AVG: %lu (%fGB/s)\n", tester->avg,
 | 
			
		||||
         size_in_gb / time_in_seconds(tester->avg, tester->cpu_freq));
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user