From befc22a61ee55d887a207153c1f5e85d0156c78b Mon Sep 17 00:00:00 2001 From: Wunkolo <Wunkolo@gmail.com> Date: Thu, 23 Dec 2021 12:37:58 -0800 Subject: [PATCH] constant_pool: Use `unordered_map` rather than `map` `map` is an ordinal structure with log(n) time searches. `unordered_map` uses O(1) average-time searches and O(n) in the worst case where a bucket has a to a colliding hash and has to start chaining. The unordered version should speed up our general-case when looking up constants. I've added a trivial order-dependent(_(0,1) and (1,0) will return a different hash_) hash to combine a 128-bit constant into a 64-bit hash that generally will not collide, using a bit-rotate to preserve entropy. --- src/dynarmic/backend/x64/constant_pool.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/dynarmic/backend/x64/constant_pool.h b/src/dynarmic/backend/x64/constant_pool.h index 16cdb236..1e4fb695 100644 --- a/src/dynarmic/backend/x64/constant_pool.h +++ b/src/dynarmic/backend/x64/constant_pool.h @@ -5,8 +5,9 @@ #pragma once -#include <map> +#include <bit> #include <tuple> +#include <unordered_map> #include <xbyak/xbyak.h> @@ -29,7 +30,13 @@ public: private: static constexpr size_t align_size = 16; // bytes - std::map<std::tuple<u64, u64>, void*> constant_info; + struct ConstantHash { + std::size_t operator()(const std::tuple<u64, u64>& constant) const { + return std::get<0>(constant) ^ std::rotl<u64>(std::get<1>(constant), 1); + } + }; + + std::unordered_map<std::tuple<u64, u64>, void*, ConstantHash> constant_info; BlockOfCode& code; size_t pool_size;