Skip to content

Commit

Permalink
Switch from murmur32 to xxhash32 for object-overlays (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
crocdialer authored Feb 16, 2025
1 parent 67499ec commit 77d73fb
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 23 deletions.
30 changes: 28 additions & 2 deletions include/vierkant/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ static inline uint32_t murmur3_32(const K &key, uint32_t seed)
// https://jcgt.org/published/0009/03/02/
inline uint32_t xxhash32(uint32_t lhs, uint32_t rhs)
{
const uint32_t PRIME32_2 = 2246822519U, PRIME32_3 = 3266489917U;
const uint32_t PRIME32_4 = 668265263U, PRIME32_5 = 374761393U;
constexpr uint32_t PRIME32_2 = 2246822519U, PRIME32_3 = 3266489917U;
constexpr uint32_t PRIME32_4 = 668265263U, PRIME32_5 = 374761393U;
uint32_t h32 = lhs + PRIME32_5 + rhs * PRIME32_3;
h32 = PRIME32_4 * ((h32 << 17) | (h32 >> (32 - 17)));
h32 = PRIME32_2 * (h32 ^ (h32 >> 15));
Expand All @@ -141,6 +141,32 @@ inline uint32_t hash_combine32(uint32_t lhs, uint32_t rhs)
return lhs ^ (rhs + 0x9e3779b9 + (lhs << 6U) + (lhs >> 2U));
}

template<typename K>
static inline uint32_t xxhash32(const K &key, uint32_t seed)
{
constexpr uint32_t num_hashes = sizeof(K) / sizeof(uint32_t);
constexpr uint32_t num_excess_bytes = sizeof(K) % sizeof(uint32_t);
uint32_t h = seed;

if constexpr(num_hashes)
{
auto ptr = reinterpret_cast<const uint32_t *>(&key), end = ptr + num_hashes;
for(; ptr < end; ++ptr) { h = xxhash32(*ptr, h); }
}
if constexpr(num_excess_bytes)
{
auto end_u8 = reinterpret_cast<const uint8_t *>(&key) + sizeof(uint32_t) * num_hashes;
uint32_t k = 0;
for(uint32_t i = num_excess_bytes; i; i--)
{
k <<= 8;
k |= end_u8[i - 1];
}
h = xxhash32(k, h);
}
return h;
}

template<class T>
inline void hash_combine(std::size_t &seed, const T &v)
{
Expand Down
4 changes: 2 additions & 2 deletions include/vierkant/linear_hashmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ class linear_hashmap
uint64_t m_capacity = 0;
uint64_t m_num_elements = 0;
std::unique_ptr<storage_item_t[]> m_storage;
hash32_fn m_hash_fn = std::bind(murmur3_32<key_t>, std::placeholders::_1, 0);
hash32_fn m_hash_fn = std::bind(xxhash32<key_t>, std::placeholders::_1, 0);

// reasonably low load-factor to keep average probe-lengths low
float m_max_load_factor = 0.5f;
Expand Down Expand Up @@ -408,7 +408,7 @@ class linear_hashmap_mt
uint64_t m_capacity{};
std::atomic<uint64_t> m_num_elements;
std::unique_ptr<storage_item_t[]> m_storage;
hash32_fn m_hash_fn = std::bind(vierkant::murmur3_32<key_t>, std::placeholders::_1, 0);
hash32_fn m_hash_fn = std::bind(vierkant::xxhash32<key_t>, std::placeholders::_1, 0);
mutable std::shared_mutex m_mutex;

// reasonably low load-factor to keep average probe-lengths low
Expand Down
1 change: 1 addition & 0 deletions shaders/fullscreen/ao_screenspace.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// rnd(state)
#include "../utils/random.glsl"
#include "../utils/hash.glsl"

// bsdf utils
#include "../utils/bsdf.glsl"
Expand Down
1 change: 1 addition & 0 deletions shaders/ray/raygen.rgen
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#extension GL_GOOGLE_include_directive : enable

#include "../utils/random.glsl"
#include "../utils/hash.glsl"
#include "../utils/bsdf.glsl"
#include "ray_common.glsl"
#include "reservoir.glsl"
Expand Down
2 changes: 1 addition & 1 deletion shaders/renderer/object_overlay.comp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct hashmap_t

uint hash(uint v)
{
return murmur3_32(v, 0);
return xxhash32(v, 0);
}

uint get(const hashmap_t hashmap, const uint key)
Expand Down
14 changes: 14 additions & 0 deletions shaders/utils/hash.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,18 @@ uint hash_combine32(uint lhs, uint rhs)
return lhs ^ (rhs + 0x9e3779b9 + (lhs << 6U) + (lhs >> 2U));
}

// Generate a random unsigned int from two unsigned int values
// @see: "Mark Jarzynski and Marc Olano, Hash Functions for GPU Rendering, Journal of Computer Graphics Techniques (JCGT), vol. 9, no. 3, 21-38, 2020"
// https://jcgt.org/published/0009/03/02/
uint xxhash32(uint lhs, uint rhs)
{
const uint PRIME32_2 = 2246822519U, PRIME32_3 = 3266489917U;
const uint PRIME32_4 = 668265263U, PRIME32_5 = 374761393U;
uint h32 = lhs + PRIME32_5 + rhs * PRIME32_3;
h32 = PRIME32_4 * ((h32 << 17) | (h32 >> (32 - 17)));
h32 = PRIME32_2 * (h32 ^ (h32 >> 15));
h32 = PRIME32_3 * (h32 ^ (h32 >> 13));
return h32 ^ (h32 >> 16);
}

#endif // UTILS_HASH_GLSL
14 changes: 0 additions & 14 deletions shaders/utils/random.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,6 @@ uint tea(uint lhs, uint rhs)
return v0;
}

// Generate a random unsigned int from two unsigned int values
// @see: "Mark Jarzynski and Marc Olano, Hash Functions for GPU Rendering, Journal of Computer Graphics Techniques (JCGT), vol. 9, no. 3, 21-38, 2020"
// https://jcgt.org/published/0009/03/02/
uint xxhash32(uint lhs, uint rhs)
{
const uint PRIME32_2 = 2246822519U, PRIME32_3 = 3266489917U;
const uint PRIME32_4 = 668265263U, PRIME32_5 = 374761393U;
uint h32 = lhs + PRIME32_5 + rhs * PRIME32_3;
h32 = PRIME32_4 * ((h32 << 17) | (h32 >> (32 - 17)));
h32 = PRIME32_2 * (h32 ^ (h32 >> 15));
h32 = PRIME32_3 * (h32 ^ (h32 >> 13));
return h32 ^ (h32 >> 16);
}

// Generate a random unsigned int in [0, 2^24) given the previous RNG state
// using the Numerical Recipes linear congruential generator
uint lcg(inout uint prev)
Expand Down
2 changes: 1 addition & 1 deletion submodules/JoltPhysics
Submodule JoltPhysics updated 446 files
2 changes: 1 addition & 1 deletion submodules/meshoptimizer
4 changes: 2 additions & 2 deletions tests/TestLinearHashmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ void test_probe_length()
// test a load-factor of 0.25
hashmap.max_load_factor(0.25f);

constexpr uint32_t test_capacity = 512;
constexpr uint32_t num_insertions = 128;
constexpr uint32_t test_capacity = 4096;
constexpr uint32_t num_insertions = 1024;
hashmap.reserve(test_capacity);

float probe_length_sum = 0.f;
Expand Down

0 comments on commit 77d73fb

Please sign in to comment.