Skip to content

Commit 8f77ddd

Browse files
committed
Add a fixed-iteration benchmark mode with per-iteration spread
1 parent 03d1acb commit 8f77ddd

1 file changed

Lines changed: 47 additions & 2 deletions

File tree

examples/bench/bench.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,44 @@
4343
#define TPM2_BENCH_DURATION_KEYGEN_SEC 15
4444
static int gUseBase2 = 1;
4545

46+
/* Fixed-iteration mode (-iter=N). Zero keeps the default duration mode, where
47+
* each algorithm runs for a wall-clock budget instead of a set count. */
48+
static int gBenchIter = 0;
49+
/* Per-iteration spread, so a single slow outlier is visible rather than
50+
* averaged away. Rejection sampling makes ML-DSA signing vary run to run. */
51+
static double gIterPrev, gIterMin, gIterMax;
52+
4653
static inline void bench_stats_start(int* count, double* start)
4754
{
4855
*count = 0;
4956
*start = gettime_secs(1);
57+
gIterPrev = *start;
58+
gIterMin = 0;
59+
gIterMax = 0;
5060
}
5161

5262
static inline int bench_stats_check(double start, int* count, double maxDurSec)
5363
{
64+
double now, each;
65+
5466
(*count)++;
55-
return ((gettime_secs(0) - start) < maxDurSec);
67+
now = gettime_secs(0);
68+
each = now - gIterPrev;
69+
gIterPrev = now;
70+
if (*count == 1) {
71+
gIterMin = each;
72+
gIterMax = each;
73+
}
74+
else if (each > gIterMax) {
75+
gIterMax = each;
76+
}
77+
else if (each < gIterMin) {
78+
gIterMin = each;
79+
}
80+
if (gBenchIter > 0) {
81+
return (*count < gBenchIter);
82+
}
83+
return ((now - start) < maxDurSec);
5684
}
5785

5886
/* countSz is number of bytes that 1 count represents. Normally bench_size,
@@ -121,8 +149,13 @@ static void bench_stats_asym_finish(const char* algo, int strength,
121149
milliEach = each * 1000; /* milliseconds */
122150

123151
printf("%-6s %5d %-9s %6d ops took %5.3f sec, avg %5.3f ms,"
124-
" %.3f ops/sec\n", algo, strength, desc,
152+
" %.3f ops/sec", algo, strength, desc,
125153
count, total, milliEach, opsSec);
154+
if (gBenchIter > 0) {
155+
printf(", min %5.3f ms, max %5.3f ms",
156+
gIterMin * 1000, gIterMax * 1000);
157+
}
158+
printf("\n");
126159
}
127160

128161
/* True if rc means the TPM does not implement the operation (so the bench
@@ -370,6 +403,9 @@ static void usage(void)
370403
printf("* -aes/xor: Use Parameter Encryption\n");
371404
printf("* -maxdur=[ms]: Maximum runtime for each algorithm in milliseconds "
372405
"(default %d)\n", TPM2_BENCH_DURATION_SEC*1000);
406+
printf("* -iter=[n]: Run each algorithm exactly n times and report the\n");
407+
printf(" average with the per-iteration min and max, instead of\n");
408+
printf(" running for a duration. Overrides -maxdur.\n");
373409
}
374410

375411
/******************************************************************************/
@@ -419,6 +455,15 @@ int TPM2_Wrapper_BenchArgs(void* userCtx, int argc, char *argv[])
419455
const char* maxStr = argv[argc-1] + XSTRLEN("-maxdur=");
420456
maxKeyGenDurSec = maxDuration = XATOI(maxStr) / 1000.0;
421457
}
458+
else if (XSTRNCMP(argv[argc-1], "-iter=", XSTRLEN("-iter=")) == 0) {
459+
const char* iterStr = argv[argc-1] + XSTRLEN("-iter=");
460+
gBenchIter = XATOI(iterStr);
461+
if (gBenchIter <= 0) {
462+
printf("Iteration count must be greater than zero\n");
463+
usage();
464+
return BAD_FUNC_ARG;
465+
}
466+
}
422467
else {
423468
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
424469
}

0 commit comments

Comments
 (0)