From ad7a12ecf30891e87a490a876180fc36c939b4a9 Mon Sep 17 00:00:00 2001 From: Moritz <49691065+mrzetti@users.noreply.github.com> Date: Mon, 22 Jun 2026 23:43:39 +0200 Subject: [PATCH] Deduplicate GPU and CPU seed outputs --- src/common.h | 16 ++++++++++++++++ src/cpu.cpp | 4 +++- src/gpu.cu | 9 +++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index c854a6d..2211243 100644 --- a/src/common.h +++ b/src/common.h @@ -5,6 +5,7 @@ #include #include #include +#include #ifndef OMISSION_LARGE_BIOMES #define OMISSION_LARGE_BIOMES 0 @@ -42,6 +43,20 @@ struct CpuOutput { int32_t score; }; +inline bool operator==(const CpuOutput &a, const CpuOutput &b) { + return a.seed == b.seed && a.x == b.x && a.z == b.z && a.score == b.score; +} + +struct CpuOutputHash { + size_t operator()(const CpuOutput &output) const { + size_t h = std::hash{}(output.seed); + h ^= std::hash{}(output.x) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + h ^= std::hash{}(output.z) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + h ^= std::hash{}(output.score) + 0x9e3779b97f4a7c15ULL + (h << 6) + (h >> 2); + return h; + } +}; + struct GpuOutputs { std::queue queue; std::mutex mutex; @@ -49,6 +64,7 @@ struct GpuOutputs { struct CpuOutputs { std::queue queue; + std::unordered_set seen; std::mutex mutex; }; diff --git a/src/cpu.cpp b/src/cpu.cpp index 287b95b..fd2997d 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -66,7 +66,9 @@ void CpuThread::run() { { std::lock_guard lock(outputs.mutex); - outputs.queue.push(output.value()); + if (outputs.seen.insert(output.value()).second) { + outputs.queue.push(output.value()); + } } } diff --git a/src/gpu.cu b/src/gpu.cu index 7d00c6b..bf221bc 100644 --- a/src/gpu.cu +++ b/src/gpu.cu @@ -1844,6 +1844,15 @@ void GpuThread::run() { h_buffer.resize(len); TRY_CUDA(cudaMemcpy(h_buffer.data(), final_outputs.data, sizeof(*h_buffer.data()) * len, cudaMemcpyDeviceToHost)); + std::sort(h_buffer.begin(), h_buffer.end(), [](const SeedPos &a, const SeedPos &b) { + if (a.seed_index != b.seed_index) return a.seed_index < b.seed_index; + if (a.x != b.x) return a.x < b.x; + return a.z < b.z; + }); + h_buffer.erase(std::unique(h_buffer.begin(), h_buffer.end(), [](const SeedPos &a, const SeedPos &b) { + return a.seed_index == b.seed_index && a.x == b.x && a.z == b.z; + }), h_buffer.end()); + { std::lock_guard lock(outputs.mutex); for (const auto &result : h_buffer) {