{ 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);
} }
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 ;
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();
}
{ 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 */
/* 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;
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 */