Add benchmarks, change project structure

This commit is contained in:
2025-10-12 10:20:09 +03:00
parent b1870bd709
commit 364d3a32ec
45 changed files with 323 additions and 51 deletions

42
bench/CMakeLists.txt Normal file
View File

@@ -0,0 +1,42 @@
# Project and C standard configuration
project(bhunit LANGUAGES C)
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_STANDARD_REQUIRED ON)
# Disable extensions
set(CMAKE_C_EXTENSIONS OFF)
# Library code
set(BHBENCH_SOURCE
src/Bench.c
)
set(BHBENCH_HEADER
include/BH/Bench.h
)
# Library
add_library(BHBench STATIC ${BHBENCH_SOURCE} ${BHBENCH_HEADER})
target_include_directories(BHBench PUBLIC include)
target_link_libraries(BHBench BHLib)
# Enable testing
include(CTest)
enable_testing()
# Search files
file(GLOB TEST_FILES "tests/*.c")
foreach(TEST_FILENAME ${TEST_FILES})
# Add test
get_filename_component(TEST_NAME ${TEST_FILENAME} NAME_WE)
add_executable("${TEST_NAME}" ${TEST_FILENAME})
target_link_libraries("${TEST_NAME}" BHLib BHBench)
add_test(NAME "${TEST_NAME}" COMMAND "${TEST_NAME}")
# Enable coverage
if(ENABLE_COVERAGE)
target_compile_options("${TEST_NAME}" PRIVATE -coverage)
target_link_options("${TEST_NAME}" PRIVATE -coverage)
endif()
endforeach()

25
bench/include/BH/Bench.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef BH_BENCH_H
#define BH_BENCH_H
typedef struct BH_Bench BH_Bench;
typedef void (*BH_BenchCallback)(BH_Bench *);
#define BH_BENCH_TEST(name) \
static void bench##name(BH_Bench *state)
#define BH_BENCH_ADD(name) \
BH_BenchAdd(#name, bench##name)
void BH_BenchAdd(const char *name,
BH_BenchCallback cb);
int BH_BenchIter(BH_Bench *state);
int BH_BenchRun(void);
#endif /* BH_BENCH_H */

112
bench/src/Bench.c Normal file
View File

@@ -0,0 +1,112 @@
#include <BH/Bench.h>
#include <BH/Timer.h>
#include <stdlib.h>
#include <stdio.h>
struct BH_Bench
{
struct BH_Bench *next;
const char *name;
BH_BenchCallback cb;
int started;
size_t iterations;
};
static BH_Bench *root = NULL;
static BH_Timer *timer = NULL;
static void cleanup(void)
{
BH_Bench *current;
current = root;
while (current)
{
BH_Bench *next = current->next;
free(current);
current = next;
}
}
void BH_BenchAdd(const char *name,
BH_BenchCallback cb)
{
BH_Bench *bench, *current;
/* Allocate and fill new benchmark entry */
bench = malloc(sizeof(*bench));
if (!bench)
return;
bench->next = NULL;
bench->name = name;
bench->cb = cb;
bench->started = 0;
bench->iterations = 0;
/* Append benchmark entry */
current = root;
while (current && current->next)
current = current->next;
if (current)
current->next = bench;
else
root = bench;
}
int BH_BenchIter(BH_Bench *state)
{
if (state->started)
{
int64_t millis;
state->iterations++;
millis = BH_TimerMilliseconds(timer);
if (millis > 1000 && state->iterations > 10)
{
printf("%s\t%f ips\n", state->name, state->iterations / (millis / 1000.0f));
return 0;
}
}
else
{
state->started = 1;
BH_TimerRestart(timer);
}
return 1;
}
int BH_BenchRun(void)
{
BH_Bench *current;
int result = 0;
timer = BH_TimerNew();
if (!timer)
{
printf("ERROR: Can't create timer for benchmarks");
return -1;
}
printf("Running benchmarks...\n");
current = root;
while (current)
{
current->cb(current);
current = current->next;
fflush(stdout);
}
cleanup();
return 0;
}

33
bench/tests/BenchVec3f.c Normal file
View File

@@ -0,0 +1,33 @@
#include <BH/Bench.h>
#include <BH/Math/Vec3f.h>
#include <stdlib.h>
BH_BENCH_TEST(Vec3f)
{
float a[3], b[3];
a[0] = (rand() % 100) / 200.0;
a[1] = (rand() % 100) / 200.0;
a[2] = (rand() % 100) / 200.0;
b[0] = (rand() % 100) / 200.0;
b[1] = (rand() % 100) / 200.0;
b[2] = (rand() % 100) / 200.0;
while (BH_BenchIter(state))
{
BH_Vec3fAdd(a, b, a);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Vec3f);
return BH_BenchRun();
}