[CRYPTO] tcrypt: Speed benchmark support for digest algorithms

This patch adds speed tests (benchmarks) for digest algorithms.
Tests are run with different buffer sizes (16 bytes, ... 8 kBytes)
and with each buffer multiple tests are run with different update()
sizes (e.g. hash 64 bytes buffer in four 16 byte updates).
There is no correctness checking of the result and all tests and
algorithms use the same input buffer.

Signed-off-by: Michal Ludvig <michal@logix.cz>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Michal Ludvig 2006-05-30 22:04:19 +10:00 committed by Herbert Xu
parent 14fdf477a7
commit e805792851
2 changed files with 206 additions and 0 deletions

View file

@ -570,6 +570,122 @@ out:
crypto_free_tfm(tfm);
}
static void test_digest_jiffies(struct crypto_tfm *tfm, char *p, int blen,
int plen, char *out, int sec)
{
struct scatterlist sg[1];
unsigned long start, end;
int bcount, pcount;
for (start = jiffies, end = start + sec * HZ, bcount = 0;
time_before(jiffies, end); bcount++) {
crypto_digest_init(tfm);
for (pcount = 0; pcount < blen; pcount += plen) {
sg_set_buf(sg, p + pcount, plen);
crypto_digest_update(tfm, sg, 1);
}
/* we assume there is enough space in 'out' for the result */
crypto_digest_final(tfm, out);
}
printk("%6u opers/sec, %9lu bytes/sec\n",
bcount / sec, ((long)bcount * blen) / sec);
return;
}
static void test_digest_cycles(struct crypto_tfm *tfm, char *p, int blen,
int plen, char *out)
{
struct scatterlist sg[1];
unsigned long cycles = 0;
int i, pcount;
local_bh_disable();
local_irq_disable();
/* Warm-up run. */
for (i = 0; i < 4; i++) {
crypto_digest_init(tfm);
for (pcount = 0; pcount < blen; pcount += plen) {
sg_set_buf(sg, p + pcount, plen);
crypto_digest_update(tfm, sg, 1);
}
crypto_digest_final(tfm, out);
}
/* The real thing. */
for (i = 0; i < 8; i++) {
cycles_t start, end;
crypto_digest_init(tfm);
start = get_cycles();
for (pcount = 0; pcount < blen; pcount += plen) {
sg_set_buf(sg, p + pcount, plen);
crypto_digest_update(tfm, sg, 1);
}
crypto_digest_final(tfm, out);
end = get_cycles();
cycles += end - start;
}
local_irq_enable();
local_bh_enable();
printk("%6lu cycles/operation, %4lu cycles/byte\n",
cycles / 8, cycles / (8 * blen));
return;
}
static void test_digest_speed(char *algo, unsigned int sec,
struct digest_speed *speed)
{
struct crypto_tfm *tfm;
char output[1024];
int i;
printk("\ntesting speed of %s\n", algo);
tfm = crypto_alloc_tfm(algo, 0);
if (tfm == NULL) {
printk("failed to load transform for %s\n", algo);
return;
}
if (crypto_tfm_alg_digestsize(tfm) > sizeof(output)) {
printk("digestsize(%u) > outputbuffer(%zu)\n",
crypto_tfm_alg_digestsize(tfm), sizeof(output));
goto out;
}
for (i = 0; speed[i].blen != 0; i++) {
if (speed[i].blen > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n",
speed[i].blen, TVMEMSIZE);
goto out;
}
printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ",
i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
memset(tvmem, 0xff, speed[i].blen);
if (sec)
test_digest_jiffies(tfm, tvmem, speed[i].blen, speed[i].plen, output, sec);
else
test_digest_cycles(tfm, tvmem, speed[i].blen, speed[i].plen, output);
}
out:
crypto_free_tfm(tfm);
}
static void test_deflate(void)
{
unsigned int i;
@ -1086,6 +1202,60 @@ static void do_test(void)
des_speed_template);
break;
case 300:
/* fall through */
case 301:
test_digest_speed("md4", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 302:
test_digest_speed("md5", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 303:
test_digest_speed("sha1", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 304:
test_digest_speed("sha256", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 305:
test_digest_speed("sha384", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 306:
test_digest_speed("sha512", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 307:
test_digest_speed("wp256", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 308:
test_digest_speed("wp384", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 309:
test_digest_speed("wp512", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 310:
test_digest_speed("tgr128", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 311:
test_digest_speed("tgr160", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 312:
test_digest_speed("tgr192", sec, generic_digest_speed_template);
if (mode > 300 && mode < 400) break;
case 399:
break;
case 1000:
test_available();
break;

View file

@ -65,6 +65,11 @@ struct cipher_speed {
unsigned int blen;
};
struct digest_speed {
unsigned int blen; /* buffer length */
unsigned int plen; /* per-update length */
};
/*
* MD4 test vectors from RFC1320
*/
@ -2975,4 +2980,35 @@ static struct cipher_speed des_speed_template[] = {
{ .klen = 0, .blen = 0, }
};
/*
* Digest speed tests
*/
static struct digest_speed generic_digest_speed_template[] = {
{ .blen = 16, .plen = 16, },
{ .blen = 64, .plen = 16, },
{ .blen = 64, .plen = 64, },
{ .blen = 256, .plen = 16, },
{ .blen = 256, .plen = 64, },
{ .blen = 256, .plen = 256, },
{ .blen = 1024, .plen = 16, },
{ .blen = 1024, .plen = 256, },
{ .blen = 1024, .plen = 1024, },
{ .blen = 2048, .plen = 16, },
{ .blen = 2048, .plen = 256, },
{ .blen = 2048, .plen = 1024, },
{ .blen = 2048, .plen = 2048, },
{ .blen = 4096, .plen = 16, },
{ .blen = 4096, .plen = 256, },
{ .blen = 4096, .plen = 1024, },
{ .blen = 4096, .plen = 4096, },
{ .blen = 8192, .plen = 16, },
{ .blen = 8192, .plen = 256, },
{ .blen = 8192, .plen = 1024, },
{ .blen = 8192, .plen = 4096, },
{ .blen = 8192, .plen = 8192, },
/* End marker */
{ .blen = 0, .plen = 0, }
};
#endif /* _CRYPTO_TCRYPT_H */