Skip to content

Commit

Permalink
Merge branch 'dev/adunn/spatial_hash_opt' into 'main'
Browse files Browse the repository at this point in the history
CPU Perf: Optmize STL usage around spatial instance caching.

See merge request lightspeedrtx/dxvk-remix-nv!969
  • Loading branch information
AlexDunn committed Sep 4, 2024
2 parents bf2e825 + 2247fdf commit bccdf94
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 10 deletions.
39 changes: 39 additions & 0 deletions src/util/util_fast_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <unordered_map>
#include <unordered_set>
#include "xxHash/xxhash.h"
#include "util_vector.h"


namespace dxvk {
Expand All @@ -34,6 +35,29 @@ namespace dxvk {
return keyval;
}
};

// A passthrough hash class compatible with std c++ containers.
struct Vector3i_hash_passthrough {
[[nodiscard]] size_t operator()(const Vector3i& keyval) const noexcept {
// Convert the 32-bit integers to 64-bit to prevent overflow in operations
size_t x = static_cast<size_t>(keyval.x);
size_t y = static_cast<size_t>(keyval.y);
size_t z = static_cast<size_t>(keyval.z);

// Constants for mixing
size_t prime1 = 0xE01658C4CA6FC337; // Large prime number
size_t prime2 = 0xF8236D0F7F1F7BF1; // Another large prime

// Perform the hashing
size_t hash = x;
hash ^= y + prime1 + (hash << 6) + (hash >> 2);
hash *= prime2;
hash ^= z + prime1 + (hash << 6) + (hash >> 2);
hash *= prime2;

return hash;
}
};

// A hash class compatible with std c++ containers.
template<typename T>
Expand Down Expand Up @@ -71,6 +95,21 @@ namespace dxvk {
// A fast set for use ONLY with already hashed keys.
struct fast_unordered_set : public std::unordered_set<XXH64_hash_t, XXH64_hash_passthrough> { };

// A fast caching structure for use ONLY with spatial data.
template<class T>
struct fast_spatial_cache : public std::unordered_map<Vector3i, T, Vector3i_hash_passthrough> {
template<typename P>
void erase_if(P&& p) {
for (auto it = this->begin(); it != this->end();) {
if (!p(it)) {
++it;
} else {
it = this->erase(it);
}
}
}
};

static bool lookupHash(const fast_unordered_set& hashList, const XXH64_hash_t& h) {
return hashList.find(h) != hashList.end();
}
Expand Down
5 changes: 3 additions & 2 deletions src/util/util_spatial_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <unordered_map>

#include "util_vector.h"
#include "util_fast_cache.h"
#include "./log/log.h"

namespace dxvk {
Expand Down Expand Up @@ -90,7 +91,7 @@ namespace dxvk {
}
}

const std::unordered_map<Vector3i, std::vector<T>>& getAll() {
const fast_spatial_cache<std::vector<T>>& getAll() {
return m_cache;
}

Expand Down Expand Up @@ -128,6 +129,6 @@ namespace dxvk {
}

float m_cellSize;
std::unordered_map<Vector3i, std::vector<T>> m_cache;
fast_spatial_cache<std::vector<T>> m_cache;
};
}
9 changes: 1 addition & 8 deletions src/util/util_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -786,11 +786,4 @@ namespace dxvk {
, w(w) {
}

}

template <>
struct std::hash<dxvk::Vector3i> {
std::size_t operator()(const dxvk::Vector3i& key) const {
return XXH3_64bits(&key, sizeof(dxvk::Vector3i));
}
};
}

0 comments on commit bccdf94

Please sign in to comment.