Skip to content

Commit

Permalink
test/benchmark.c: test with different buffer sizes
Browse files Browse the repository at this point in the history
Read buffer sizes and batch sizes from a data table.
  • Loading branch information
aklomp committed Mar 5, 2016
1 parent ef2a0cb commit 4f53441
Showing 1 changed file with 60 additions and 29 deletions.
89 changes: 60 additions & 29 deletions test/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
#include "../include/libbase64.h"
#include "codec_supported.h"

#define INSIZE_MB 10
#define KB 1024
#define MB (1024 * KB)

#define RANDOMDEV "/dev/urandom"

struct buffers {
Expand All @@ -22,10 +24,25 @@ struct buffers {
size_t encsz;
};

// Define buffer sizes to test with:
static struct bufsize {
char *label;
size_t len;
int repeat;
int batch;
}
sizes[] = {
{ "10 MB", MB * 10, 10, 1 },
{ "1 MB", MB * 1, 10, 10 },
{ "100 KB", KB * 100, 10, 100 },
{ "10 KB", KB * 10, 100, 100 },
{ "1 KB", KB * 1, 100, 1000 },
};

static inline float
bytes_to_mb (size_t bytes)
{
return bytes / 1024.0f / 1024.0f;
return bytes / (float) MB;
}

static bool
Expand Down Expand Up @@ -62,54 +79,68 @@ timediff_sec (struct timespec *start, struct timespec *end)
}

static void
codec_bench_enc (struct buffers *b, const char *name, unsigned int flags)
codec_bench_enc (struct buffers *b, const struct bufsize *bs, const char *name, unsigned int flags)
{
float timediff, fastest = -1.0f;
struct timespec start, end;

// For short enc repeat the process multiple times to increase timer accuracy:
int nrepeats = (10 * 1024 * 1024 * INSIZE_MB) / b->regsz;
// Reset buffer size:
b->regsz = bs->len;

// Repeat benchmark a number of times for a fair test:
for (int i = bs->repeat; i; i--) {

// Choose fastest of ten runs:
for (int i = 0; i < 10; i++) {
// Timing loop, use batches to increase timer resolution:
clock_gettime(CLOCK_REALTIME, &start);
for (int j = 0; j < nrepeats; j++)
for (int j = bs->batch; j; j--)
base64_encode(b->reg, b->regsz, b->enc, &b->encsz, flags);
clock_gettime(CLOCK_REALTIME, &end);
timediff = timediff_sec(&start, &end) / nrepeats;

// Calculate average time of batch:
timediff = timediff_sec(&start, &end) / bs->batch;

// Update fastest time seen:
if (fastest < 0.0f || timediff < fastest)
fastest = timediff;
}

printf("%s\tencode\t%.02f MB/sec\n", name, bytes_to_mb(b->regsz) / fastest);
}

static void
codec_bench_dec (struct buffers *b, const char *name, unsigned int flags)
codec_bench_dec (struct buffers *b, const struct bufsize *bs, const char *name, unsigned int flags)
{
float timediff, fastest = -1.0f;
struct timespec start, end;

// For short enc repeat the process multiple times to increase timer accuracy:
int nrepeats = (10 * 1024 * 1024 * INSIZE_MB * 4) / 3 / b->encsz;
// Reset buffer size:
b->encsz = bs->len;

// Repeat benchmark a number of times for a fair test:
for (int i = bs->repeat; i; i--) {

// Choose fastest of ten runs:
for (int i = 0; i < 10; i++) {
// Timing loop, use batches to increase timer resolution:
clock_gettime(CLOCK_REALTIME, &start);
for (int j = 0; j < nrepeats; j++)
for (int j = bs->batch; j; j--)
base64_decode(b->enc, b->encsz, b->reg, &b->regsz, flags);
clock_gettime(CLOCK_REALTIME, &end);
timediff = timediff_sec(&start, &end) / nrepeats;

// Calculate average time of batch:
timediff = timediff_sec(&start, &end) / bs->batch;

// Update fastest time seen:
if (fastest < 0.0f || timediff < fastest)
fastest = timediff;
}

printf("%s\tdecode\t%.02f MB/sec\n", name, bytes_to_mb(b->encsz) / fastest);
}

static void
codec_bench (struct buffers *b, const char *name, unsigned int flags)
codec_bench (struct buffers *b, const struct bufsize *bs, const char *name, unsigned int flags)
{
codec_bench_enc(b, name, flags);
codec_bench_dec(b, name, flags);
codec_bench_enc(b, bs, name, flags);
codec_bench_dec(b, bs, name, flags);
}

int
Expand All @@ -118,10 +149,10 @@ main ()
int ret = 0;
char *errmsg = NULL;
struct buffers b;
size_t len[] = { 0, 1048576, 102400, 10240, 1024 };

len[0] = b.regsz = 1024 * 1024 * INSIZE_MB;
b.encsz = 1024 * 1024 * ((INSIZE_MB * 5) / 3);
// Set buffer sizes to largest buffer length:
b.regsz = sizes[0].len;
b.encsz = sizes[0].len * 5 / 3;

// Allocate space for megabytes of random data:
if ((b.reg = malloc(b.regsz)) == NULL) {
Expand All @@ -143,15 +174,15 @@ main ()
goto err2;
}

// Loop over all buffer lengths:
for (size_t j = 0; j < sizeof(len) / sizeof(len[0]); j++) {
b.regsz = len[j];
printf("Testing with buffer length %d\n", (int)b.regsz);
// Loop over all buffer sizes:
for (size_t i = 0; i < sizeof(sizes) / sizeof(sizes[0]); i++) {
printf("Testing with buffer size %s, fastest of %d * %d\n",
sizes[i].label, sizes[i].repeat, sizes[i].batch);

// Loop over all codecs:
for (size_t i = 0; codecs[i]; i++)
if (codec_supported(1 << i))
codec_bench(&b, codecs[i], 1 << i);
for (size_t j = 0; codecs[j]; j++)
if (codec_supported(1 << j))
codec_bench(&b, &sizes[i], codecs[j], 1 << j);
};

// Free memory:
Expand Down

0 comments on commit 4f53441

Please sign in to comment.