btrfs-progs: crypto: add hash speedtest utility
A simple tool to microbenchmark performance of the hashes. Uses rdtsc for timing, so works only on x86_64. $ make hash-speedtest $ ./hash-speedtest [iterations] Block size: 4096 Iterations: 100000 NULL-NOP: cycles: 56061823, c/i 560 NULL-MEMCPY: cycles: 61296469, c/i 612 CRC32C: cycles: 179961796, c/i 1799 XXHASH: cycles: 138434590, c/i 1384 Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
8c5756ec8d
commit
785073f658
4
Makefile
4
Makefile
|
@ -646,6 +646,10 @@ fssum: tests/fssum.c crypto/sha224-256.c
|
||||||
@echo " [LD] $@"
|
@echo " [LD] $@"
|
||||||
$(Q)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
$(Q)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
hash-speedtest: crypto/hash-speedtest.c $(objects) $(libs_static)
|
||||||
|
@echo " [LD] $@"
|
||||||
|
$(Q)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
test-build: test-build-pre test-build-real
|
test-build: test-build-pre test-build-real
|
||||||
|
|
||||||
test-build-pre:
|
test-build-pre:
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include "../kerncompat.h"
|
||||||
|
#include "crypto/hash.h"
|
||||||
|
#include "crypto/crc32c.h"
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
|
#error "Only x86_64 supported"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const int blocksize = 4096;
|
||||||
|
int iterations = 100000;
|
||||||
|
|
||||||
|
static __always_inline unsigned long long rdtsc(void)
|
||||||
|
{
|
||||||
|
unsigned low, high;
|
||||||
|
|
||||||
|
asm volatile("rdtsc" : "=a" (low), "=d" (high));
|
||||||
|
|
||||||
|
return (low | ((u64)(high) << 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 read_tsc(void)
|
||||||
|
{
|
||||||
|
asm volatile("mfence");
|
||||||
|
return rdtsc();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the input and copy last bytes as the hash */
|
||||||
|
static int hash_null_memcpy(const u8 *buf, size_t length, u8 *out)
|
||||||
|
{
|
||||||
|
const u8 *end = buf + length;
|
||||||
|
|
||||||
|
while (buf + CRYPTO_HASH_SIZE_MAX < end) {
|
||||||
|
memcpy(out, buf, CRYPTO_HASH_SIZE_MAX);
|
||||||
|
buf += CRYPTO_HASH_SIZE_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test overhead of the calls */
|
||||||
|
static int hash_null_nop(const u8 *buf, size_t length, u8 *out)
|
||||||
|
{
|
||||||
|
memset(out, 0xFF, CRYPTO_HASH_SIZE_MAX);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
u8 buf[blocksize];
|
||||||
|
u8 hash[32];
|
||||||
|
int idx;
|
||||||
|
int iter;
|
||||||
|
struct contestant {
|
||||||
|
char name[16];
|
||||||
|
int (*digest)(const u8 *buf, size_t length, u8 *out);
|
||||||
|
int digest_size;
|
||||||
|
u64 cycles;
|
||||||
|
} contestants[] = {
|
||||||
|
{ .name = "NULL-NOP", .digest = hash_null_nop, .digest_size = 32 },
|
||||||
|
{ .name = "NULL-MEMCPY", .digest = hash_null_memcpy, .digest_size = 32 },
|
||||||
|
{ .name = "CRC32C", .digest = hash_crc32c, .digest_size = 4 },
|
||||||
|
{ .name = "XXHASH", .digest = hash_xxhash, .digest_size = 8 },
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
iterations = atoi(argv[1]);
|
||||||
|
if (iterations < 0)
|
||||||
|
iterations = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc32c_optimization_init();
|
||||||
|
memset(buf, 0, 4096);
|
||||||
|
|
||||||
|
printf("Block size: %d\n", blocksize);
|
||||||
|
printf("Iterations: %d\n", iterations);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
for (idx = 0; idx < ARRAY_SIZE(contestants); idx++) {
|
||||||
|
struct contestant *c = &contestants[idx];
|
||||||
|
u64 start, end;
|
||||||
|
|
||||||
|
printf("% 12s: ", c->name);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
start = read_tsc();
|
||||||
|
for (iter = 0; iter < iterations; iter++) {
|
||||||
|
memset(buf, iter & 0xFF, blocksize);
|
||||||
|
memset(hash, 0, 32);
|
||||||
|
c->digest(buf, blocksize, hash);
|
||||||
|
}
|
||||||
|
end = read_tsc();
|
||||||
|
c->cycles = end - start;
|
||||||
|
|
||||||
|
printf("cycles: % 12llu, c/i % 8llu\n",
|
||||||
|
(unsigned long long)c->cycles,
|
||||||
|
(unsigned long long)c->cycles / iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue