initFn will be measured once, benchFn will be measured `nbLoops` times */ initFn is optional, provide NULL if none */ benchFn must return a size_t value that errorFn can interpret */ takes # of blocks and list of size & stuff for each. */ can report result of benchFn for each block into blockResult. */ blockResult is optional, provide NULL if this information is not required */ note : time per loo
| 106 | /* blockResult is optional, provide NULL if this information is not required */ |
| 107 | /* note : time per loop can be reported as zero if run time < timer resolution */ |
| 108 | BMK_runOutcome_t BMK_benchFunction(BMK_benchParams_t p, |
| 109 | unsigned nbLoops) |
| 110 | { |
| 111 | size_t dstSize = 0; |
| 112 | nbLoops += !nbLoops; /* minimum nbLoops is 1 */ |
| 113 | |
| 114 | /* init */ |
| 115 | { size_t i; |
| 116 | for(i = 0; i < p.blockCount; i++) { |
| 117 | memset(p.dstBuffers[i], 0xE5, p.dstCapacities[i]); /* warm up and erase result buffer */ |
| 118 | } } |
| 119 | |
| 120 | /* benchmark */ |
| 121 | { UTIL_time_t const clockStart = UTIL_getTime(); |
| 122 | unsigned loopNb, blockNb; |
| 123 | if (p.initFn != NULL) p.initFn(p.initPayload); |
| 124 | for (loopNb = 0; loopNb < nbLoops; loopNb++) { |
| 125 | for (blockNb = 0; blockNb < p.blockCount; blockNb++) { |
| 126 | size_t const res = p.benchFn(p.srcBuffers[blockNb], p.srcSizes[blockNb], |
| 127 | p.dstBuffers[blockNb], p.dstCapacities[blockNb], |
| 128 | p.benchPayload); |
| 129 | if (loopNb == 0) { |
| 130 | if (p.blockResults != NULL) p.blockResults[blockNb] = res; |
| 131 | if ((p.errorFn != NULL) && (p.errorFn(res))) { |
| 132 | RETURN_QUIET_ERROR(BMK_runOutcome_error(res), |
| 133 | "Function benchmark failed on block %u (of size %u) with error %i", |
| 134 | blockNb, (unsigned)p.srcSizes[blockNb], (int)res); |
| 135 | } |
| 136 | dstSize += res; |
| 137 | } } |
| 138 | } /* for (loopNb = 0; loopNb < nbLoops; loopNb++) */ |
| 139 | |
| 140 | { PTime const totalTime = UTIL_clockSpanNano(clockStart); |
| 141 | BMK_runTime_t rt; |
| 142 | rt.nanoSecPerRun = (double)totalTime / nbLoops; |
| 143 | rt.sumOfReturn = dstSize; |
| 144 | return BMK_setValid_runTime(rt); |
| 145 | } } |
| 146 | } |
| 147 | |
| 148 | |
| 149 | /* ==== Benchmarking any function, providing intermediate results ==== */ |
no test coverage detected