mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git
synced 2024-11-24 12:44:17 +08:00
btrfs-progs: crypto: add time-based measurement to hash-speedtest
People are interested in measuring the hash performance on non-x86_64 architectures. Add option to do time-based measurements (in nanoseconds) in case there's no support for clock-based measurements. $ ./hash-speedtest --cycles Block size: 4096 Iterations: 100000 Implementation: builtin Units: cycles NULL-NOP: cycles: 43035633, cycles/i 430 NULL-MEMCPY: cycles: 72478624, cycles/i 724 CRC32C: cycles: 181712982, cycles/i 1817 XXHASH: cycles: 136251305, cycles/i 1362 SHA256: cycles: 10758567410, cycles/i 107585 BLAKE2b: cycles: 2249704806, cycles/i 22497 $ ./hash-speedtest --time Block size: 4096 Iterations: 100000 Implementation: builtin Units: nsecs NULL-NOP: nsecs: 12459033, nsecs/i 124 NULL-MEMCPY: nsecs: 20687845, nsecs/i 206 CRC32C: nsecs: 52648264, nsecs/i 526 XXHASH: nsecs: 39591766, nsecs/i 395 SHA256: nsecs: 3079668837, nsecs/i 30796 BLAKE2b: nsecs: 644766582, nsecs/i 6447 Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
f123c28412
commit
55bf9b749d
@ -58,6 +58,8 @@ AC_CHECK_FUNCS([openat], [],
|
||||
|
||||
AC_CHECK_FUNCS([reallocarray])
|
||||
|
||||
AC_CHECK_FUNCS([clock_gettime])
|
||||
|
||||
m4_ifndef([PKG_PROG_PKG_CONFIG],
|
||||
[m4_fatal([Could not locate the pkg-config autoconf
|
||||
macros. These are usually located in /usr/share/aclocal/pkg.m4.
|
||||
|
@ -1,16 +1,21 @@
|
||||
#include "../kerncompat.h"
|
||||
#include <time.h>
|
||||
#include <getopt.h>
|
||||
#include "crypto/hash.h"
|
||||
#include "crypto/crc32c.h"
|
||||
#include "crypto/sha.h"
|
||||
#include "crypto/blake2.h"
|
||||
|
||||
#ifndef __x86_64__
|
||||
#error "Only x86_64 supported"
|
||||
#ifdef __x86_64__
|
||||
static const int cycles_supported = 1;
|
||||
#else
|
||||
static const int cycles_supported = 0;
|
||||
#endif
|
||||
|
||||
const int blocksize = 4096;
|
||||
int iterations = 100000;
|
||||
|
||||
#ifdef __x86_64__
|
||||
static __always_inline unsigned long long rdtsc(void)
|
||||
{
|
||||
unsigned low, high;
|
||||
@ -26,6 +31,22 @@ static inline u64 read_tsc(void)
|
||||
return rdtsc();
|
||||
}
|
||||
|
||||
#define get_cycles() read_tsc()
|
||||
|
||||
#else
|
||||
|
||||
#define get_cycles() (0)
|
||||
|
||||
#endif
|
||||
|
||||
static inline u64 get_time(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
|
||||
}
|
||||
|
||||
/* Read the input and copy last bytes as the hash */
|
||||
static int hash_null_memcpy(const u8 *buf, size_t length, u8 *out)
|
||||
{
|
||||
@ -47,6 +68,15 @@ static int hash_null_nop(const u8 *buf, size_t length, u8 *out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *units_to_str(int units)
|
||||
{
|
||||
switch (units) {
|
||||
case 0: return "cycles";
|
||||
case 1: return "nsecs";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
u8 buf[blocksize];
|
||||
u8 hash[32];
|
||||
@ -65,9 +95,40 @@ int main(int argc, char **argv) {
|
||||
{ .name = "SHA256", .digest = hash_sha256, .digest_size = 32 },
|
||||
{ .name = "BLAKE2b", .digest = hash_blake2b, .digest_size = 32 },
|
||||
};
|
||||
int units = 0;
|
||||
|
||||
if (argc > 1) {
|
||||
iterations = atoi(argv[1]);
|
||||
optind = 0;
|
||||
while (1) {
|
||||
static const struct option long_options[] = {
|
||||
{ "cycles", no_argument, NULL, 'c' },
|
||||
{ "time", no_argument, NULL, 't' },
|
||||
{ NULL, 0, NULL, 0}
|
||||
};
|
||||
int c;
|
||||
|
||||
c = getopt_long(argc, argv, "ct", long_options, NULL);
|
||||
if (c < 0)
|
||||
break;
|
||||
switch (c) {
|
||||
case 'c':
|
||||
if (!cycles_supported) {
|
||||
fprintf(stderr,
|
||||
"ERROR: cannot measure cycles on this arch, use --time\n");
|
||||
return 1;
|
||||
}
|
||||
units = 0;
|
||||
break;
|
||||
case 't':
|
||||
units = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ERROR: unknown option\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind >= 1) {
|
||||
iterations = atoi(argv[optind]);
|
||||
if (iterations < 0)
|
||||
iterations = 1;
|
||||
}
|
||||
@ -78,6 +139,7 @@ int main(int argc, char **argv) {
|
||||
printf("Block size: %d\n", blocksize);
|
||||
printf("Iterations: %d\n", iterations);
|
||||
printf("Implementation: %s\n", CRYPTOPROVIDER);
|
||||
printf("Units: %s\n", units_to_str(units));
|
||||
printf("\n");
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(contestants); idx++) {
|
||||
@ -87,17 +149,19 @@ int main(int argc, char **argv) {
|
||||
printf("% 12s: ", c->name);
|
||||
fflush(stdout);
|
||||
|
||||
start = read_tsc();
|
||||
start = (units ? get_time() : get_cycles());
|
||||
for (iter = 0; iter < iterations; iter++) {
|
||||
memset(buf, iter & 0xFF, blocksize);
|
||||
memset(hash, 0, 32);
|
||||
c->digest(buf, blocksize, hash);
|
||||
}
|
||||
end = read_tsc();
|
||||
end = (units ? get_time() : get_cycles());
|
||||
c->cycles = end - start;
|
||||
|
||||
printf("cycles: % 12llu, c/i % 8llu\n",
|
||||
printf("%: % 12llu, %s/i % 8llu\n",
|
||||
units_to_str(units),
|
||||
(unsigned long long)c->cycles,
|
||||
units_to_str(units),
|
||||
(unsigned long long)c->cycles / iterations);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user