From f75ad2edcf3525597137a1c9da35e58ecd279e94 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 25 Jan 2019 14:22:25 -0800 Subject: [PATCH] added ability to create timedFnState on stack --- programs/benchfn.c | 19 ++++++++++++++----- programs/benchfn.h | 17 ++++++++++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/programs/benchfn.c b/programs/benchfn.c index f5118d087..a27d91a07 100644 --- a/programs/benchfn.c +++ b/programs/benchfn.c @@ -148,7 +148,7 @@ BMK_runOutcome_t BMK_benchFunction(BMK_benchParams_t p, { U64 const totalTime = UTIL_clockSpanNano(clockStart); BMK_runTime_t rt; - rt.nanoSecPerRun = totalTime / nbLoops; + rt.nanoSecPerRun = (double)totalTime / nbLoops; rt.sumOfReturn = dstSize; return BMK_setValid_runTime(rt); } } @@ -178,6 +178,15 @@ void BMK_freeTimedFnState(BMK_timedFnState_t* state) { free(state); } +BMK_timedFnState_t* BMK_initStatic_timedFnState(void* buffer, size_t size, unsigned total_ms, unsigned run_ms) +{ + BMK_timedFnState_t* const r = (BMK_timedFnState_t*)buffer; + if (size < sizeof(struct BMK_timedFnState_s)) return NULL; + if ((size_t)buffer % 8) return NULL; /* must be aligned on 8-bytes boundaries */ + BMK_resetTimedFnState(r, total_ms, run_ms); + return r; +} + void BMK_resetTimedFnState(BMK_timedFnState_t* timedFnState, unsigned total_ms, unsigned run_ms) { if (!total_ms) total_ms = 1 ; @@ -186,7 +195,7 @@ void BMK_resetTimedFnState(BMK_timedFnState_t* timedFnState, unsigned total_ms, timedFnState->timeSpent_ns = 0; timedFnState->timeBudget_ns = (U64)total_ms * TIMELOOP_NANOSEC / 1000; timedFnState->runBudget_ns = (U64)run_ms * TIMELOOP_NANOSEC / 1000; - timedFnState->fastestRun.nanoSecPerRun = (U64)(-1LL); + timedFnState->fastestRun.nanoSecPerRun = (double)TIMELOOP_NANOSEC * 2000000000; /* hopefully large enough : must be larger than any potential measurement */ timedFnState->fastestRun.sumOfReturn = (size_t)(-1LL); timedFnState->nbLoops = 1; timedFnState->coolTime = UTIL_getTime(); @@ -231,13 +240,13 @@ BMK_runOutcome_t BMK_benchTimedFn(BMK_timedFnState_t* cont, } { BMK_runTime_t const newRunTime = BMK_extract_runTime(runResult); - U64 const loopDuration_ns = newRunTime.nanoSecPerRun * cont->nbLoops; + double const loopDuration_ns = newRunTime.nanoSecPerRun * cont->nbLoops; - cont->timeSpent_ns += loopDuration_ns; + cont->timeSpent_ns += (unsigned long long)loopDuration_ns; /* estimate nbLoops for next run to last approximately 1 second */ if (loopDuration_ns > (runBudget_ns / 50)) { - U64 const fastestRun_ns = MIN(bestRunTime.nanoSecPerRun, newRunTime.nanoSecPerRun); + double const fastestRun_ns = MIN(bestRunTime.nanoSecPerRun, newRunTime.nanoSecPerRun); cont->nbLoops = (U32)(runBudget_ns / fastestRun_ns) + 1; } else { /* previous run was too short : blindly increase workload by x multiplier */ diff --git a/programs/benchfn.h b/programs/benchfn.h index aa3c3e939..737dfa995 100644 --- a/programs/benchfn.h +++ b/programs/benchfn.h @@ -31,7 +31,7 @@ extern "C" { /* BMK_runTime_t: valid result return type */ typedef struct { - unsigned long long nanoSecPerRun; /* time per iteration (over all blocks) */ + double nanoSecPerRun; /* time per iteration (over all blocks) */ size_t sumOfReturn; /* sum of return values */ } BMK_runTime_t; @@ -160,6 +160,21 @@ void BMK_resetTimedFnState(BMK_timedFnState_t* timedFnState, unsigned total_ms, void BMK_freeTimedFnState(BMK_timedFnState_t* state); +/* BMK_timedFnState_shell and BMK_initStatic_timedFnState() : + * Makes it possible to statically allocate a BMK_timedFnState_t on stack. + * BMK_timedFnState_shell is only there to allocate space, + * never ever access its members. + * BMK_timedFnState_t() actually accepts any buffer. + * It will check if provided buffer is large enough and is correctly aligned, + * and will return NULL if conditions are not respected. + */ +#define BMK_TIMEDFNSTATE_SIZE 56 +typedef union { + char never_access_space[BMK_TIMEDFNSTATE_SIZE]; + long long alignment_enforcer; /* must be aligned on 8-bytes boundaries */ +} BMK_timedFnState_shell; +BMK_timedFnState_t* BMK_initStatic_timedFnState(void* buffer, size_t size, unsigned total_ms, unsigned run_ms); + #endif /* BENCH_FN_H_23876 */