WIP: add a 128bit function XXH64X2 based on XXH64 #518
No reviewers
Labels
No labels
announcement
bug
build
CI
dependencies
documentation
duplicate
enhancement
experience feedback
feature request
github_actions
help wanted
install
invalid
Long-term
optimization
portability
question
target-specific
test issue
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-Cyan4973/xxHash!518
Loading…
Reference in a new issue
No description provided.
Delete branch "work/xxh64x2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
XXH64X2is modified directly fromXXH64, and the low 64bits are the same asXXH64. The purpose is that when porting to an environment without SIMD vectoring,XXH64is is still faster thanXXH3andXXH128. The new function can cover the 128b hash usage on these environments.The new hash has passed all the smhasher tests and the collision ratio tests as 128b hash. The performance is about 85% of the
XXH64. While porting to the java, the performance is 95% of theXXH64.Thanks for the suggestion @gzm55 .
A question on the design goal :
is it supposed to be a 128-bit hash,
or a 64-bit hash which outputs a 128-bit return value ?
it is a 128-bit hash.
When cannot take the benefit of the SIMD instructions, a 128-bit hash is very rare with both high quality and high speed. The
XXH64use four 64-bit integers internal state for the main 32-byte strip loop, so it could be a good candidate to output 128-bit hash. Comparing to hash twice with two different XXH64 seeds (XXH64 + XXH64), the new algorithm reuse the most avalanche operations and got a better speed. The nameXXH64X2expresses two meaning: a) it is based onXXH64, 2) it generate 128 bit output (64 x 2)I think this is rather redundant. We already have XXH3 which is much faster.
Well, the suggested
XXH64x2uses a design that has been envisioned as a possible backup strategy forXXH128. IfXXH3had not worked as intended, I probably would have considered something similar, aka anXXH64variant.There are a few things that made me consider it a "second" choice rather than a first, and so it's interesting to ask a few questions about that.
XXH64also a poor fit.So, the question is :
XXH64). That means that, although internal states is 256-bit, it's still composed of independent 64-bit lanes. Therefore, the collision ratio might be closer to 64-bit rather than 128-bit.smhasherwas really meant to measure entropy of 32-bit hashes. It's just unable to provide accurate measurements for 64-bit hashes, let alone 128-bit hashes.smhasheron each one of them.xxh64x2, since the low one is equivalent to regularxxh64which was already validated using this method.Indeed. That is my main concern. ARM64 and x86_64 machine both require NEON and SSE2, respectively, where the XXH3 implementation is significantly faster than XXH64.
Additionally, XXH64 has some known flaws in its core loop.
It feels like developing a new sword when lightsabers already exist.
There might be a valid reason.
Let just @gzm55 answer.
The JVM on x64 is this kind of environment. After trying to port the xxh3/128 to native java code, the performance is 30%~40% of xxhash64. Even jni or new vector api of jdk16 still take much overhead and cannot keep up the the xxhash64.
Yes, all the collisions tests on the xxh128 from the wiki are passed (zero collisions). And on the high 64 bit part, 294 collisions are found within 100G inputs with length of 256byte.
xxh64x2borrow some of methods fromxxh128for generating 128 bit results from internal state. And two independent hashes with 64-bit of entropy can be combined as a 128-bit hash with full width entropy.For high 64 bits part, the
smhashertests and collision tests are both passed.For two 32bits parts (65-96 and 97-128) pass all the smhashers tests except LongNeighbors giving some warnings:
Good point, I wasn't even considering virtual machines.
It is true that scalar XXH3 is slower than XXH64. However, that seems to be a bit much.
What about a hybrid JNI/Java version? The overhead of JNI is pretty nasty and the short keys are all available in Java intrinsics, so it is only worth it on long keys.
Looking at the new vector API, I doubt XXH3 will work well with it, as it seems rather half-baked. It lacks shifting [wtf?!] and long multiplication.
I would like to see those implementations, though. Perhaps they can be improved.
yes, this is a major candidate method, and the split length becomes another tuning point.
It is still under incubator, and cannot 1-to-1 map the api to instructions of X64 arch. This set of api would not graduates in LTS JDK17, so even the api can boost the jdk to control all instructions, the industry (big data, spring, etc.) may need at least a decade to accept and deploy the new LTS JDK with vector api.
NB: OpenHFT/Zero-Allocation-Hashing#58 is the draft of pure java porting of xxh3.
Anyway, imo,
XXH64X2, as a fast scalar version of 128-bit hash, could have its position, although it depends on 64bit multiplications.I spent some time testing the proposed variant
xxh64x2.In a test generating 100 Billion hashes, I got 1 collision.
This may not sound like much, but such an occurrence is supposed to have an unbelievably small probably, at a 1 / 59029581036420320 rate, so it doesn't feel like "just bad luck".
While it's fairly difficult to pinpoint exactly the limit,
it seems to me that this 128-bit hash doesn't provide 128-bit of entropy.
It's still larger than 64-bit, but rather around ~80-bit,
Unfortunately, I can't access a platform powerful enough to more accurately estimate the entropy.
Depending on the target application, it may still be good enough.
But better be aware of it.
@Cyan4973 does the
xxh128pass with similar test and got 0 collision? and I also wonder for larger hash algos (256+ bits), how to prove the entropy bit.Yes it does.
Arguably, it's not a proof that
xxh128has achieved real 128-bit entropy. It's more a "minimum" to achieve.In the future, systems with more RAM would make it possible to increase the measurement accuracy. I doubt we'll ever have enough to reach 128-bit, but given that the hash doesn't target cryptographic quality, that's not necessarily a "big problem". Even ~100-bit entropy is plenty-enough for most applications out there.
@Cyan4973 the collision test hash samples with a fixed length. It could be better to sample strings over a range of length, which is more like the real use cases and avoid the overfit of segment hash algorithm.
I am guessing that this collision is related to #54.
Closing. I applaud the effort, but it's difficult to introduce this variant within
xxHashlibrary without also introducing confusion for library users. From an ecosystem perspective, I would prefer to spend the effort ensuring thatXXH128is fast enough for your needs, though I understand that specific setups, such as JVM on x64, may play against its natural strengths.Pull request closed