Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Z
zstd
Manage
Activity
Members
Plan
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CodeLinaro
yocto-mirrors
zstd
Commits
9867cdb8
Commit
9867cdb8
authored
6 years ago
by
Yann Collet
Browse files
Options
Downloads
Patches
Plain Diff
benchfn can provided faulty return value
with BMK_extract_returnValue()
parent
d38063f8
Loading
Loading
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
programs/benchfn.c
+22
-21
22 additions, 21 deletions
programs/benchfn.c
programs/benchfn.h
+50
-42
50 additions, 42 deletions
programs/benchfn.h
with
72 additions
and
63 deletions
programs/benchfn.c
+
22
−
21
View file @
9867cdb8
...
...
@@ -48,9 +48,9 @@
#define DEBUGOUTPUT(...) { if (DEBUG) DISPLAY(__VA_ARGS__); }
/* error without displaying */
#define RETURN_QUIET_ERROR(
errorNum,
retValue, ...) { \
#define RETURN_QUIET_ERROR(retValue, ...) {
\
DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \
DEBUGOUTPUT("Error
%i : ", errorNum);
\
DEBUGOUTPUT("Error
: ");
\
DEBUGOUTPUT(__VA_ARGS__); \
DEBUGOUTPUT(" \n"); \
return retValue; \
...
...
@@ -63,41 +63,48 @@
int
BMK_isSuccessful_runOutcome
(
BMK_runOutcome_t
outcome
)
{
return
outcome
.
tag
==
0
;
return
outcome
.
error_tag_never_ever_use_directly
==
0
;
}
/* warning : this function will stop program execution if outcome is invalid !
* check outcome validity first, using BMK_isValid_runResult() */
BMK_runTime_t
BMK_extract_runTime
(
BMK_runOutcome_t
outcome
)
{
assert
(
outcome
.
tag
==
0
);
return
outcome
.
internal_never_use_directly
;
assert
(
outcome
.
error_tag_never_ever_use_directly
==
0
);
return
outcome
.
internal_never_
ever_
use_directly
;
}
static
BMK_runOutcome_t
BMK_runOutcome_error
(
void
)
size_t
BMK_extract_errorResult
(
BMK_runOutcome_t
outcome
)
{
assert
(
outcome
.
error_tag_never_ever_use_directly
!=
0
);
return
outcome
.
error_result_never_ever_use_directly
;
}
static
BMK_runOutcome_t
BMK_runOutcome_error
(
size_t
errorResult
)
{
BMK_runOutcome_t
b
;
memset
(
&
b
,
0
,
sizeof
(
b
));
b
.
tag
=
1
;
b
.
error_tag_never_ever_use_directly
=
1
;
b
.
error_result_never_ever_use_directly
=
errorResult
;
return
b
;
}
static
BMK_runOutcome_t
BMK_setValid_runTime
(
BMK_runTime_t
runTime
)
{
BMK_runOutcome_t
outcome
;
outcome
.
tag
=
0
;
outcome
.
internal_never_use_directly
=
runTime
;
outcome
.
error_tag_never_ever_use_directly
=
0
;
outcome
.
internal_never_
ever_
use_directly
=
runTime
;
return
outcome
;
}
/* 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
compliant with errorFn
*/
/* 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 loop c
ould be
zero if run time < timer resolution */
/* note : time per loop c
an be reported as
zero if run time < timer resolution */
BMK_runOutcome_t
BMK_benchFunction
(
BMK_benchFn_t
benchFn
,
void
*
benchPayload
,
BMK_initFn_t
initFn
,
void
*
initPayload
,
...
...
@@ -109,10 +116,7 @@ BMK_runOutcome_t BMK_benchFunction(
unsigned
nbLoops
)
{
size_t
dstSize
=
0
;
if
(
!
nbLoops
)
{
RETURN_QUIET_ERROR
(
2
,
BMK_runOutcome_error
(),
"nbLoops must be nonzero "
);
}
nbLoops
+=
!
nbLoops
;
/* minimum nbLoops is 1 */
/* init */
{
size_t
i
;
...
...
@@ -138,11 +142,8 @@ BMK_runOutcome_t BMK_benchFunction(
dstBlockBuffers
[
blockNb
],
dstBlockCapacities
[
blockNb
],
benchPayload
);
if
(
loopNb
==
0
)
{
if
(
errorFn
!=
NULL
)
if
(
errorFn
(
res
))
{
BMK_runOutcome_t
ro
=
BMK_runOutcome_error
();
ro
.
internal_never_use_directly
.
sumOfReturn
=
res
;
RETURN_QUIET_ERROR
(
2
,
ro
,
if
((
errorFn
!=
NULL
)
&&
(
errorFn
(
res
)))
{
RETURN_QUIET_ERROR
(
BMK_runOutcome_error
(
res
),
"Function benchmark failed on block %u (of size %u) with error %i"
,
blockNb
,
(
U32
)
srcBlockBuffers
[
blockNb
],
(
int
)
res
);
}
...
...
@@ -246,7 +247,7 @@ BMK_runOutcome_t BMK_benchTimedFn(
cont
->
nbLoops
);
if
(
!
BMK_isSuccessful_runOutcome
(
runResult
))
{
/* error : move out */
return
BMK_runOutcome_error
()
;
return
runResult
;
}
{
BMK_runTime_t
const
newRunTime
=
BMK_extract_runTime
(
runResult
);
...
...
This diff is collapsed.
Click to expand it.
programs/benchfn.h
+
50
−
42
View file @
9867cdb8
...
...
@@ -26,39 +26,29 @@ extern "C" {
#include
<stddef.h>
/* size_t */
/* ===
Variant
=== */
/* ===
=
Benchmark any function, iterated on a set of blocks =
=== */
/* Creates a variant `typeName`, able to express "error or valid result".
* Functions with return type `typeName`
* must first check if result is valid, using BMK_isSuccessful_*(),
* and only then can extract `baseType`.
*/
#define VARIANT_ERROR_RESULT(baseType, variantName) \
\
typedef struct { \
baseType internal_never_use_directly; \
int tag; \
} variantName
/* ==== Benchmarking any function, iterated on a set of blocks ==== */
/* BMK_runTime_t: valid result type */
typedef
struct
{
unsigned
long
long
nanoSecPerRun
;
/* time per iteration */
size_t
sumOfReturn
;
/* sum of return values */
unsigned
long
long
nanoSecPerRun
;
/* time per iteration
(over all blocks)
*/
size_t
sumOfReturn
;
/* sum of return values */
}
BMK_runTime_t
;
VARIANT_ERROR_RESULT
(
BMK_runTime_t
,
BMK_runOutcome_t
);
/* declares BMK_runOutcome_t */
/* check first if the return structure represents an error or a valid result */
int
BMK_isSuccessful_runOutcome
(
BMK_runOutcome_t
outcome
);
/* extract result from variant type.
* note : this function will abort() program execution if result is not valid.
* check result validity first, by using BMK_isSuccessful_runOutcome()
*/
BMK_runTime_t
BMK_extract_runTime
(
BMK_runOutcome_t
outcome
);
/* type expressing the outcome of a benchmark run by BMK_benchFunction().
* benchmark outcome might be valid or invalid.
* benchmark outcome can be invalid if and errorFn was provided.
* BMK_runOutcome_t must be considered "opaque" : never access its members directly.
* Instead, use its assigned methods :
* BMK_isSuccessful_runOutcome, BMK_extract_runTime, BMK_extract_errorResult.
* The structure is only described here to allow its allocation on stack. */
typedef
struct
{
BMK_runTime_t
internal_never_ever_use_directly
;
size_t
error_result_never_ever_use_directly
;
int
error_tag_never_ever_use_directly
;
}
BMK_runOutcome_t
;
typedef
size_t
(
*
BMK_benchFn_t
)(
const
void
*
src
,
size_t
srcSize
,
void
*
dst
,
size_t
dstCapacity
,
void
*
customPayload
);
...
...
@@ -71,19 +61,20 @@ typedef unsigned (*BMK_errorFn_t)(size_t);
/* benchFn - (*benchFn)(srcBuffers[i], srcSizes[i], dstBuffers[i], dstCapacities[i], benchPayload)
* is run nbLoops times
* initFn - (*initFn)(initPayload) is run once per
benchmark
, at the beginning.
* initFn - (*initFn)(initPayload) is run once per
run
, at the beginning.
* This argument can be NULL, in which case nothing is run.
* errorFn - is a function run on each return value of benchFn.
* Argument errorFn can be NULL, in which case nothing is run.
* Otherwise, it must return 0 when benchFn was successful, and >= 1 if it detects an error.
* Execution is stopped as soon as an error is detected, and the triggering return value is stored into sumOfReturn.
* Execution is stopped as soon as an error is detected,
* the triggering return value can then be retrieved with BMK_extract_errorResult().
* blockCount - number of blocks. Size of all array parameters : srcBuffers, srcSizes, dstBuffers, dstCapacities, blockResults
* srcBuffers - an array of buffers to be operated on by benchFn
* srcSizes - an array of the sizes of above buffers
* dstBuffers - an array of buffers to be written into by benchFn
* dstCapacities - an array of the capacities of above buffers
* blockResults - Optional: store the return value of benchFn for each block. Use NULL if this result is not requested.
* nbLoops - defines number of times benchFn is run.
* nbLoops - defines number of times benchFn is run.
Minimum value is 1. A 0 is interpreted as a 1.
* @return: a variant, which express either an error, or can generate a valid BMK_runTime_t result.
* Use BMK_isSuccessful_runOutcome() to check if function was successful.
* If yes, extract the result with BMK_extract_runTime(),
...
...
@@ -105,25 +96,29 @@ BMK_runOutcome_t BMK_benchFunction(
/* ==== Benchmark any function, returning intermediate results ==== */
/* check first if the benchmark was successful or not */
int
BMK_isSuccessful_runOutcome
(
BMK_runOutcome_t
outcome
);
/* state information tracking benchmark session */
typedef
struct
BMK_timedFnState_s
BMK_timedFnState_t
;
/* If the benchmark was successful, extract the result.
* note : this function will abort() program execution if benchmark failed !
* always check if benchmark was successful first !
*/
BMK_runTime_t
BMK_extract_runTime
(
BMK_runOutcome_t
outcome
);
/* BMK_createTimedFnState() and BMK_resetTimedFnState() :
* Create/Set BMK_timedFnState_t for next benchmark session,
* which shall last a minimum of total_ms milliseconds,
* producing intermediate results, paced at interval of (approximately) run_ms.
/* when benchmark failed, it means one invocation of `benchFn` failed.
* The failure was detected by `errorFn`, operating on return value of `benchFn`.
* Returns the faulty return value.
* note : this function will abort() program execution if benchmark did not failed.
* always check if benchmark failed first !
*/
BMK_timedFnState_t
*
BMK_createTimedFnState
(
unsigned
total_ms
,
unsigned
run_ms
);
void
BMK_resetTimedFnState
(
BMK_timedFnState_t
*
timedFnState
,
unsigned
total_ms
,
unsigned
run_ms
);
void
BMK_freeTimedFnState
(
BMK_timedFnState_t
*
state
);
size_t
BMK_extract_errorResult
(
BMK_runOutcome_t
outcome
);
/* Tells if duration of all benchmark runs has exceeded total_ms
*/
int
BMK_isCompleted_TimedFn
(
const
BMK_timedFnState_t
*
timedFnState
);
/* ==== Benchmark any function, returning intermediate results ==== */
/* state information tracking benchmark session */
typedef
struct
BMK_timedFnState_s
BMK_timedFnState_t
;
/* BMK_benchTimedFn() :
* Similar to BMK_benchFunction(), most arguments being identical.
...
...
@@ -143,6 +138,19 @@ BMK_runOutcome_t BMK_benchTimedFn(
void
*
const
*
dstBlockBuffers
,
const
size_t
*
dstBlockCapacities
,
size_t
*
blockResults
);
/* Tells if duration of all benchmark runs has exceeded total_ms
*/
int
BMK_isCompleted_TimedFn
(
const
BMK_timedFnState_t
*
timedFnState
);
/* BMK_createTimedFnState() and BMK_resetTimedFnState() :
* Create/Set BMK_timedFnState_t for next benchmark session,
* which shall last a minimum of total_ms milliseconds,
* producing intermediate results, paced at interval of (approximately) run_ms.
*/
BMK_timedFnState_t
*
BMK_createTimedFnState
(
unsigned
total_ms
,
unsigned
run_ms
);
void
BMK_resetTimedFnState
(
BMK_timedFnState_t
*
timedFnState
,
unsigned
total_ms
,
unsigned
run_ms
);
void
BMK_freeTimedFnState
(
BMK_timedFnState_t
*
state
);
#endif
/* BENCH_FN_H_23876 */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment