Selaa lähdekoodia

Added 64-bit hashing function to speed up body pair hashing (#469)

HashBytes is looping through the key byte by byte which is approximately 3x slower than this implementation
Speeds up the Ragdoll performance test by 1-2%
Jorrit Rouwe 2 vuotta sitten
vanhempi
commit
ec7ca49224
2 muutettua tiedostoa jossa 23 lisäystä ja 3 poistoa
  1. 17 0
      Jolt/Core/HashCombine.h
  2. 6 3
      Jolt/Physics/Body/BodyPair.h

+ 17 - 0
Jolt/Core/HashCombine.h

@@ -23,6 +23,23 @@ inline uint64 HashBytes(const void *inData, uint inSize, uint64 inSeed = 0xcbf29
 	return hash;
 }
 
+/// A 64 bit hash function by Thomas Wang, Jan 1997
+/// See: http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
+/// @param inValue Value to hash
+/// @return Hash
+inline uint64 Hash64(uint64 inValue)
+{
+	uint64 hash = inValue;
+	hash = (~hash) + (hash << 21); // hash = (hash << 21) - hash - 1;
+	hash = hash ^ (hash >> 24);
+	hash = (hash + (hash << 3)) + (hash << 8); // hash * 265
+	hash = hash ^ (hash >> 14);
+	hash = (hash + (hash << 2)) + (hash << 4); // hash * 21
+	hash = hash ^ (hash >> 28);
+	hash = hash + (hash << 31);
+	return hash;
+}
+
 /// @brief Helper function that hashes a single value into ioSeed
 /// Taken from: https://stackoverflow.com/questions/2590677/how-do-i-combine-hash-values-in-c0x
 template <typename T>

+ 6 - 3
Jolt/Physics/Body/BodyPair.h

@@ -19,15 +19,18 @@ struct alignas(uint64) BodyPair
 							BodyPair(BodyID inA, BodyID inB)							: mBodyA(inA), mBodyB(inB) { }
 
 	/// Equals operator
-	bool					operator == (const BodyPair &inRHS) const					{ static_assert(sizeof(*this) == sizeof(uint64), "Mismatch in class size"); return *reinterpret_cast<const uint64 *>(this) == *reinterpret_cast<const uint64 *>(&inRHS); }
+	bool					operator == (const BodyPair &inRHS) const					{ return *reinterpret_cast<const uint64 *>(this) == *reinterpret_cast<const uint64 *>(&inRHS); }
 
 	/// Smaller than operator, used for consistently ordering body pairs
-	bool					operator < (const BodyPair &inRHS) const					{ static_assert(sizeof(*this) == sizeof(uint64), "Mismatch in class size"); return *reinterpret_cast<const uint64 *>(this) < *reinterpret_cast<const uint64 *>(&inRHS); }
+	bool					operator < (const BodyPair &inRHS) const					{ return *reinterpret_cast<const uint64 *>(this) < *reinterpret_cast<const uint64 *>(&inRHS); }
 
-	uint64					GetHash() const												{ return HashBytes(this, sizeof(BodyPair)); }
+	/// Get the hash value of this object
+	uint64					GetHash() const												{ return Hash64(*reinterpret_cast<const uint64 *>(this)); }
 
 	BodyID					mBodyA;
 	BodyID					mBodyB;
 };
 
+static_assert(sizeof(BodyPair) == sizeof(uint64), "Mismatch in class size");
+
 JPH_NAMESPACE_END