From 5fb8f32b76396f3d9d92203cc35fd6d6a195fce2 Mon Sep 17 00:00:00 2001 From: cosmo Date: Sun, 23 Aug 2026 00:34:02 +0100 Subject: [PATCH] parallel TT init Bench: 13860644 --- src/tt.cpp | 31 ++++++++++++++++++++++++++----- src/tt.hpp | 20 ++++++++++---------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/tt.cpp b/src/tt.cpp index 4fee1c47..828df701 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -1,5 +1,8 @@ #include "tt.hpp" #include // For std::min +#include +#include +#include namespace Clockwork { @@ -172,11 +175,29 @@ void TT::resize(size_t mb) { } void TT::clear() { - for (size_t i = 0; i < m_size; ++i) { - m_clusters[i].data[0].store(0, std::memory_order_relaxed); - m_clusters[i].data[1].store(0, std::memory_order_relaxed); - m_clusters[i].data[2].store(0, std::memory_order_relaxed); - m_clusters[i].data[3].store(0, std::memory_order_relaxed); + constexpr size_t MB16 = 16 * 1024 * 1024; + + if (m_size == 0) { + return; + } + + size_t max_useful = std::max(1, m_size * sizeof(TTClusterMemory) / MB16); + size_t thread_count = + std::min(max_useful, std::max(1, std::thread::hardware_concurrency())); + + auto clear_range = [this](size_t begin, size_t end) { + std::memset(&m_clusters[begin], 0, (end - begin) * sizeof(TTClusterMemory)); + }; + + std::vector threads; + threads.reserve(thread_count - 1); + for (size_t t = 1; t < thread_count; ++t) { + threads.emplace_back(clear_range, m_size * t / thread_count, + m_size * (t + 1) / thread_count); + } + clear_range(0, m_size / thread_count); + for (auto& thread : threads) { + thread.join(); } } diff --git a/src/tt.hpp b/src/tt.hpp index 8488ebd9..09a54d35 100644 --- a/src/tt.hpp +++ b/src/tt.hpp @@ -40,23 +40,23 @@ struct TTCluster { }; struct TTClusterMemory { - alignas(32) std::array, 4> data; + alignas(32) std::array data; - [[nodiscard]] auto load() const -> TTCluster { + [[nodiscard]] auto load() -> TTCluster { std::array out; - out[0] = this->data[0].load(std::memory_order_relaxed); - out[1] = this->data[1].load(std::memory_order_relaxed); - out[2] = this->data[2].load(std::memory_order_relaxed); - out[3] = this->data[3].load(std::memory_order_relaxed); + out[0] = std::atomic_ref{this->data[0]}.load(std::memory_order_relaxed); + out[1] = std::atomic_ref{this->data[1]}.load(std::memory_order_relaxed); + out[2] = std::atomic_ref{this->data[2]}.load(std::memory_order_relaxed); + out[3] = std::atomic_ref{this->data[3]}.load(std::memory_order_relaxed); return std::bit_cast(out); } auto store(TTCluster cluster) { std::array mem = std::bit_cast>(cluster); - this->data[0].store(mem[0], std::memory_order_relaxed); - this->data[1].store(mem[1], std::memory_order_relaxed); - this->data[2].store(mem[2], std::memory_order_relaxed); - this->data[3].store(mem[3], std::memory_order_relaxed); + std::atomic_ref{this->data[0]}.store(mem[0], std::memory_order_relaxed); + std::atomic_ref{this->data[1]}.store(mem[1], std::memory_order_relaxed); + std::atomic_ref{this->data[2]}.store(mem[2], std::memory_order_relaxed); + std::atomic_ref{this->data[3]}.store(mem[3], std::memory_order_relaxed); } };