[sheepdog] [PATCH 1/7] optimize fnv hash
MORITA Kazutaka
morita.kazutaka at gmail.com
Fri Aug 30 11:32:03 CEST 2013
From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
FNV hash author says that a expression of shifts and adds is faster
than FNV_prime multiply (*). However, with the recent GCC and
hardware, it looks like the FNV_prime multiply generates much faster
code.
This patch uses FNV_64_PRIME to generate codes, and adds fnv_64a_64 to
create a hash value from 64 bit integers faster. Note that this patch
is just for optimization and will not change the generated hash
values.
(*) http://www.isthe.com/chongo/tech/comp/fnv/#gcc-O3
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
include/sheepdog_proto.h | 39 +++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 06523ea..845dac6 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -224,17 +224,44 @@ struct sheepdog_vdi_attr {
/* 64 bit FNV-1a non-zero initial basis */
#define FNV1A_64_INIT ((uint64_t) 0xcbf29ce484222325ULL)
+#define FNV_64_PRIME ((uint64_t) 0x100000001b3ULL)
/* 64 bit Fowler/Noll/Vo FNV-1a hash code */
static inline uint64_t fnv_64a_buf(const void *buf, size_t len, uint64_t hval)
{
- unsigned char *bp = (unsigned char *) buf;
- unsigned char *be = bp + len;
- while (bp < be) {
- hval ^= (uint64_t) *bp++;
- hval += (hval << 1) + (hval << 4) + (hval << 5) +
- (hval << 7) + (hval << 8) + (hval << 40);
+ const unsigned char *p = (const unsigned char *) buf;
+
+ for (int i = 0; i < len; i++) {
+ hval ^= (uint64_t) p[i];
+ hval *= FNV_64_PRIME;
}
+
+ return hval;
+}
+
+/*
+ * The result is same as fnv_64a_buf(&oid, sizeof(oid), hval) but this function
+ * is a bit faster.
+ */
+static inline uint64_t fnv_64a_64(uint64_t oid, uint64_t hval)
+{
+ hval ^= oid & 0xff;
+ hval *= FNV_64_PRIME;
+ hval ^= oid >> 8 & 0xff;
+ hval *= FNV_64_PRIME;
+ hval ^= oid >> 16 & 0xff;
+ hval *= FNV_64_PRIME;
+ hval ^= oid >> 24 & 0xff;
+ hval *= FNV_64_PRIME;
+ hval ^= oid >> 32 & 0xff;
+ hval *= FNV_64_PRIME;
+ hval ^= oid >> 40 & 0xff;
+ hval *= FNV_64_PRIME;
+ hval ^= oid >> 48 & 0xff;
+ hval *= FNV_64_PRIME;
+ hval ^= oid >> 56 & 0xff;
+ hval *= FNV_64_PRIME;
+
return hval;
}
--
1.7.9.5
More information about the sheepdog
mailing list