Improve speed benchmark stability with adaptive 1 ms sampling and best-result selection

This commit is contained in:
Andrea Mazzoleni 2026-09-09 16:19:20 +02:00
parent 2b784748e3
commit bc564e7465
2 changed files with 74 additions and 101 deletions

View file

@ -24,28 +24,33 @@ static int64_t diffgettimeofday(struct timeval* start, struct timeval* stop)
return d;
}
/**
* Start time measurement.
*/
/* INDENT-OFF */
#define SPEED_START \
count = 0; \
gettimeofday(&start, 0); \
do { \
for (i = 0; i < delta; ++i)
/* INDENT-ON */
{ \
int speed_delta_ = delta; \
int64_t elapsed_ = 0; \
int64_t best_dt_ = INT64_MAX; \
do { \
struct timeval start; \
struct timeval stop; \
gettimeofday(&start, 0); \
for (int i_ = 0; i_ < speed_delta_; ++i_)
/**
* Stop time measurement.
*/
/* INDENT-OFF */
#define SPEED_STOP \
count += delta; \
gettimeofday(&stop, 0); \
} while (diffgettimeofday(&start, &stop) < period * 1000LL); \
ds = size * (int64_t)count * nd; \
dt = diffgettimeofday(&start, &stop);
/* INDENT-ON */
dt = diffgettimeofday(&start, &stop); \
if (dt < 1000 && speed_delta_ <= INT_MAX / 2) { \
speed_delta_ *= 2; \
elapsed_ = 0; \
best_dt_ = INT64_MAX; \
continue; \
} \
elapsed_ += dt; \
if (dt < best_dt_) \
best_dt_ = dt; \
} while (elapsed_ < period * 1000LL); \
ds = size * (int64_t)speed_delta_ * nd; \
dt = best_dt_; \
}
/**
* Global variable used to propagate side effects.
@ -57,20 +62,17 @@ unsigned side_effect;
void speed_mem(int nd, void** v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i, j;
int count;
int i;
printf("Memory write speed using the C memset() function:\n");
printf("%8s", "memset");
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
memset(v[j], j, size);
for (i = 0; i < nd; ++i)
memset(v[i], i, size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
@ -80,12 +82,9 @@ void speed_mem(int nd, void** v, int size, int delta, int period)
void speed_crc(int nd, void** v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i, j;
int count;
int i;
/* crc table */
printf("CRC used to check the content file integrity:\n");
@ -94,8 +93,8 @@ void speed_crc(int nd, void** v, int size, int delta, int period)
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
side_effect += crc32c_gen(0, v[j], size);
for (i = 0; i < nd; ++i)
side_effect += crc32c_gen(0, v[i], size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
@ -107,8 +106,8 @@ void speed_crc(int nd, void** v, int size, int delta, int period)
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
side_effect += crc32c_x86(0, v[j], size);
for (i = 0; i < nd; ++i)
side_effect += crc32c_x86(0, v[i], size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
@ -121,8 +120,8 @@ void speed_crc(int nd, void** v, int size, int delta, int period)
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
side_effect += crc32c_arm64(0, v[j], size);
for (i = 0; i < nd; ++i)
side_effect += crc32c_arm64(0, v[i], size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
@ -134,12 +133,9 @@ void speed_crc(int nd, void** v, int size, int delta, int period)
void speed_hash(int nd, void** v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i, j;
int count;
int i;
unsigned char digest[HASH_MAX];
unsigned char seed[HASH_MAX];
@ -162,24 +158,24 @@ void speed_hash(int nd, void** v, int size, int delta, int period)
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
memhash(HASH_MURMUR3, seed, digest, v[j], size);
for (i = 0; i < nd; ++i)
memhash(HASH_MURMUR3, seed, digest, v[i], size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
memhash(HASH_SPOOKY2, seed, digest, v[j], size);
for (i = 0; i < nd; ++i)
memhash(HASH_SPOOKY2, seed, digest, v[i], size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
memhash(HASH_MUSEAIR, seed, digest, v[j], size);
for (i = 0; i < nd; ++i)
memhash(HASH_MUSEAIR, seed, digest, v[i], size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
@ -189,12 +185,8 @@ void speed_hash(int nd, void** v, int size, int delta, int period)
void speed_gen(int nd, void** v, int size, int delta, int period, const char* msg)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i;
int count;
int mode = raid_mode(RAID_MODE_GET);
/* RAID table */
@ -1076,12 +1068,8 @@ void speed_gen(int nd, void** v, int size, int delta, int period, const char* ms
void speed_genz(int nd, void** v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i;
int count;
/* Vandermonde table */
printf("Vandermonde functions used for computing parity with 'sync':\n");
@ -1199,12 +1187,9 @@ void speed_genz(int nd, void** v, int size, int delta, int period)
void speed_rec(int nd, void** v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i;
int count;
int id[RAID_PARITY_MAX];
int ip[RAID_PARITY_MAX];
@ -2358,9 +2343,8 @@ void speed(int period, int nd, int size)
else
size *= KIBI;
if (period < 1)
period = 1000;
delta = period >= 1000 ? 10 : 1;
period = 250;
delta = 1; /* auto increased in SPEED_START */
nv = nd + RAID_PARITY_MAX;

View file

@ -10,11 +10,16 @@
#include <sys/time.h>
#include <stdio.h>
#include <inttypes.h>
#include <limits.h>
/*
* Size of the blocks to test.
*/
#ifdef COVERAGE
#define TEST_SIZE (4 * 1024)
#else
#define TEST_SIZE (256 * 1024)
#endif
/*
* Number of data blocks to test.
@ -34,52 +39,47 @@ static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
return d;
}
/**
* Test period.
*/
#ifdef COVERAGE
#define TEST_PERIOD 100000LL
#define TEST_DELTA 1
#else
#define TEST_PERIOD 1000000LL
#define TEST_DELTA 10
#endif
/**
* Start time measurement.
*/
#define SPEED_START \
count = 0; \
gettimeofday(&start, 0); \
{ \
int speed_delta_ = delta; \
int64_t elapsed_ = 0; \
int64_t best_dt_ = INT64_MAX; \
do { \
for (i = 0; i < delta; ++i)
struct timeval start; \
struct timeval stop; \
gettimeofday(&start, 0); \
for (int i_ = 0; i_ < speed_delta_; ++i_)
/**
* Stop time measurement.
*/
#define SPEED_STOP \
count += delta; \
gettimeofday(&stop, 0); \
} while (diffgettimeofday(&start, &stop) < period); \
ds = size * (int64_t)count * nd; \
dt = diffgettimeofday(&start, &stop);
dt = diffgettimeofday(&start, &stop); \
if (dt < 1000 && speed_delta_ <= INT_MAX / 2) { \
speed_delta_ *= 2; \
elapsed_ = 0; \
best_dt_ = INT64_MAX; \
continue; \
} \
elapsed_ += dt; \
if (dt < best_dt_) \
best_dt_ = dt; \
} while (elapsed_ < period * 1000LL); \
ds = size * (int64_t)speed_delta_ * nd; \
dt = best_dt_; \
}
void speed_mem(int nd, void **v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i, j;
int count;
int i;
printf("Memory write speed using the C memset() function:\n");
printf("%8s", "memset");
fflush(stdout);
SPEED_START {
for (j = 0; j < nd; ++j)
memset(v[j], j, size);
for (i = 0; i < nd; ++i)
memset(v[i], i, size);
} SPEED_STOP
printf("%8" PRIu64, ds / dt);
@ -89,12 +89,8 @@ void speed_mem(int nd, void **v, int size, int delta, int period)
void speed_gen(int nd, void **v, int size, int delta, int period, const char *msg)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i;
int count;
int mode = raid_mode(RAID_MODE_GET);
/* RAID table */
@ -972,12 +968,8 @@ void speed_gen(int nd, void **v, int size, int delta, int period, const char *ms
void speed_genz(int nd, void **v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i;
int count;
/* Vandermonde table */
printf("Vandermonde functions used for computing the parity:\n");
@ -1095,14 +1087,11 @@ void speed_genz(int nd, void **v, int size, int delta, int period)
void speed_rec(int nd, void **v, int size, int delta, int period)
{
struct timeval start;
struct timeval stop;
int64_t ds;
int64_t dt;
int i;
int id[RAID_PARITY_MAX];
int ip[RAID_PARITY_MAX];
int count;
/* basic disks and parity mapping */
for (i = 0; i < RAID_PARITY_MAX; ++i) {
@ -2138,8 +2127,8 @@ void speed(void)
void **v;
int i;
int size = TEST_SIZE;
int delta = TEST_DELTA;
int period = TEST_PERIOD;
int period = 250;
int delta = 1; /* auto increased in SPEED_START */
nv = nd + RAID_PARITY_MAX;