From 0538a6d11a703a3aa23fb484c21986aa29c6b15b Mon Sep 17 00:00:00 2001 From: chylex <contact@chylex.com> Date: Thu, 10 Feb 2022 18:23:49 +0100 Subject: [PATCH] Add benchmark timing to ASM projects --- 2015/01/CMakeLists.txt | 2 +- 2015/01/main.asm | 6 ++-- 2015/utils/benchmark.h | 67 ++++++++++++++++++++++++++++++++++++++++++ 2015/utils/main.c | 21 +++++++++++-- 4 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 2015/utils/benchmark.h diff --git a/2015/01/CMakeLists.txt b/2015/01/CMakeLists.txt index c1732d1..027e16f 100644 --- a/2015/01/CMakeLists.txt +++ b/2015/01/CMakeLists.txt @@ -6,4 +6,4 @@ enable_language(ASM_NASM) set(CMAKE_NASM_LINK_EXECUTABLE "ld <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") set(CAN_USE_ASSEMBLER TRUE) -add_executable(${PROJECT_NAME} main.asm ../utils/main.c ../utils/file.h) +add_executable(${PROJECT_NAME} main.asm ../utils/main.c ../utils/file.h ../utils/benchmark.h) diff --git a/2015/01/main.asm b/2015/01/main.asm index ba04711..7e7d282 100644 --- a/2015/01/main.asm +++ b/2015/01/main.asm @@ -1,5 +1,5 @@ bits 32 -extern _printf +extern _print section .data @@ -51,11 +51,11 @@ _entryPoint: .end: push eax push dword print_final_floor - call _printf + call _print push edi push dword print_first_entered_basement - call _printf + call _print pop edi pop ebx diff --git a/2015/utils/benchmark.h b/2015/utils/benchmark.h new file mode 100644 index 0000000..8f92a01 --- /dev/null +++ b/2015/utils/benchmark.h @@ -0,0 +1,67 @@ +#ifndef ADVENTOFCODE_BENCHMARK_H +#define ADVENTOFCODE_BENCHMARK_H + +#include "stdio.h" + +#if WIN32 +#include "windows.h" +#else +#include "time.h" +#endif + +static int sortDoubles(const void* a, const void* b) { + double x = *(double*) a; + double y = *(double*) b; + + if (x > y) { + return 1; + } + else if (x < y) { + return -1; + } + else { + return 0; + } +} + +static void formatMillis(const char* text, const double ms) { + if (ms >= 0.1) { + printf("\n%s: %.2f ms", text, ms); + } + else { + printf("\n%s: %.2f us", text, ms * 1000.0); + } +} + +typedef void (*entryPointCallback)(char* input); + +#define BENCHMARK_RUNS 50001 + +void runBenchmark(const entryPointCallback ep, char* input) { + double benchmarkResults[BENCHMARK_RUNS]; + for (int run = 0; run < BENCHMARK_RUNS; run++) { + #if WIN32 + LARGE_INTEGER startTime, endTime, frequency; + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&startTime); + ep(input); + QueryPerformanceCounter(&endTime); + benchmarkResults[run] = (double) (endTime.QuadPart - startTime.QuadPart) * 1000.0 / (double) frequency.QuadPart; + #else + clock_t startTime = clock(); + ep(input); + clock_t endTime = clock(); + benchmarkResults[run] = ((endTime - startTime) * 1000.0) / CLOCKS_PER_SEC; + #endif + } + + qsort(benchmarkResults, BENCHMARK_RUNS, sizeof(double), sortDoubles); + + formatMillis("Median elapsed time", benchmarkResults[BENCHMARK_RUNS / 2]); + formatMillis("Q1 elapsed time", benchmarkResults[(BENCHMARK_RUNS * 25) / 100]); + formatMillis("Q3 elapsed time", benchmarkResults[(BENCHMARK_RUNS * 75) / 100]); +} + +#undef BENCHMARK_RUNS + +#endif //ADVENTOFCODE_BENCHMARK_H diff --git a/2015/utils/main.c b/2015/utils/main.c index 0e1ea8d..dd69ba5 100644 --- a/2015/utils/main.c +++ b/2015/utils/main.c @@ -1,15 +1,30 @@ +#include "stdarg.h" #include "file.h" +#include "benchmark.h" -void entryPoint(char* input); +void entryPoint(char *input); -int main() { - char* input = readFile("input/1.txt"); +int enableOutput = 1; + +extern void print(const char *format, ...) { + if (enableOutput) { + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + } +} + +int main(void) { + char *input = readFile("input/1.txt"); if (input == NULL) { return 1; } else { entryPoint(input); + enableOutput = 0; + runBenchmark(entryPoint, input); return 0; } }