From 53ba29b2887e9c9bad98b5e130ad87b46fdf5c4c Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sun, 13 Nov 2022 17:05:29 +0100 Subject: [PATCH] Optimized crypto cache memory allocation --- src/crypto.cpp | 53 ++++++++++++++++++++++++++++++++++++++-------- src/p2pool.cpp | 17 +++++++++++++++ src/side_chain.cpp | 12 ++++++++++- 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/crypto.cpp b/src/crypto.cpp index 1b42c94..f505e6a 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -217,12 +217,8 @@ public: { WriteLock lock(derivations_lock); - DerivationEntry& entry = derivations->emplace(index, DerivationEntry{ derivation, {} }).first->second; - - const uint32_t k = static_cast(output_index << 8) | view_tag; - if (std::find(entry.m_viewTags.begin(), entry.m_viewTags.end(), k) == entry.m_viewTags.end()) { - entry.m_viewTags.emplace_back(k); - } + DerivationEntry& entry = derivations->emplace(index, DerivationEntry{ derivation, { 0xFFFFFFFFUL, 0xFFFFFFFFUL }, {} }).first->second; + entry.add_view_tag(static_cast(output_index << 8) | view_tag); } return true; @@ -308,16 +304,19 @@ public: WriteLock lock(derivations_lock); delete derivations; derivations = new DerivationsMap(); + derivations->reserve(5000); } { WriteLock lock(public_keys_lock); delete public_keys; public_keys = new PublicKeysMap(); + public_keys->reserve(5000); } { WriteLock lock(tx_keys_lock); delete tx_keys; tx_keys = new TxKeysMap(); + tx_keys->reserve(50); } } @@ -325,10 +324,24 @@ private: struct DerivationEntry { hash m_derivation; - std::vector m_viewTags; + uint32_t m_viewTags1[2] = { 0xFFFFFFFFUL, 0xFFFFFFFFUL }; + std::vector m_viewTags2; - bool find_view_tag(size_t output_index, uint8_t& view_tag) const { - for (uint32_t k : m_viewTags) { + FORCEINLINE bool find_view_tag(size_t output_index, uint8_t& view_tag) const + { +#define ITER(i) do { \ + const uint32_t k = m_viewTags1[i]; \ + if ((k >> 8) == output_index) { \ + view_tag = static_cast(k); \ + return true; \ + } \ + } while(0) + + ITER(0); + ITER(1); +#undef ITER + + for (const uint32_t k : m_viewTags2) { if ((k >> 8) == output_index) { view_tag = static_cast(k); return true; @@ -336,6 +349,28 @@ private: } return false; } + + FORCEINLINE void add_view_tag(uint32_t k) + { +#define ITER(i) do { \ + const uint32_t t = m_viewTags1[i]; \ + if (t == 0xFFFFFFFFUL) { \ + m_viewTags1[i] = k; \ + return; \ + } \ + else if (t == k) { \ + return; \ + } \ + } while (0) + + ITER(0); + ITER(1); +#undef ITER + + if (std::find(m_viewTags2.begin(), m_viewTags2.end(), k) == m_viewTags2.end()) { + m_viewTags2.emplace_back(k); + } + } }; typedef unordered_map, DerivationEntry> DerivationsMap; diff --git a/src/p2pool.cpp b/src/p2pool.cpp index b3cd226..331c703 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -1444,6 +1444,23 @@ static void on_signal(uv_signal_t* handle, int signum) static bool init_uv_threadpool() { +#ifdef _MSC_VER +#define putenv _putenv +#endif + + const uint32_t N = std::max(std::min(std::thread::hardware_concurrency(), 4U), 8U); + LOGINFO(4, "running " << N << " threads in the UV thread pool"); + + char buf[40] = {}; + log::Stream s(buf); + s << "UV_THREADPOOL_SIZE=" << N << '\0'; + + int err = putenv(buf); + if (err != 0) { + err = errno; + LOGWARN(1, "Couldn't set UV thread pool size to " << N << " threads, putenv returned error " << err); + } + static uv_work_t dummy; return (uv_queue_work(uv_default_loop_checked(), &dummy, [](uv_work_t*) {}, nullptr) == 0); } diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 0e7cd39..7761d7c 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -744,7 +744,17 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v int num_helper_jobs_started = 0; if (loop) { - constexpr size_t HELPER_JOBS_COUNT = 4; + uint32_t HELPER_JOBS_COUNT = std::thread::hardware_concurrency(); + + // this thread will also be running, so reduce helper job count by 1 + if (HELPER_JOBS_COUNT > 0) { + --HELPER_JOBS_COUNT; + } + + // No more than 8 helper jobs because our UV worker thread pool has 8 threads + if (HELPER_JOBS_COUNT > 8) { + HELPER_JOBS_COUNT = 8; + } struct Work {