From ecb7b77326b0d72e0d468316531e4d6a3f348ec4 Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Sat, 15 Apr 2023 10:02:56 +0200 Subject: [PATCH] Latte: Use better hashing algorithm for cache invalidation Decreases chance of hash collisions while also being faster due to 4 channel vectorization --- src/Cafe/HW/Latte/Core/LatteBufferCache.cpp | 38 ++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp b/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp index 7c484bcb..b5c1d901 100644 --- a/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp +++ b/src/Cafe/HW/Latte/Core/LatteBufferCache.cpp @@ -734,20 +734,34 @@ private: static uint64 hashPage(uint8* mem) { - // note - this algorithm is/was also baked into pageWriteStreamoutSignatures() - uint64 h = 0; - uint64* memU64 = (uint64*)mem; - for (uint32 i = 0; i < CACHE_PAGE_SIZE / 8; i++) - { - //h = _rotr64(h, 7); - //h ^= *memU64; - //memU64++; + static const uint64 k0 = 0x55F23EAD; + static const uint64 k1 = 0x185FDC6D; + static const uint64 k2 = 0xF7431F49; + static const uint64 k3 = 0xA4C7AE9D; - h = std::rotr(h, 7); - h += (*memU64 + (uint64)i); - memU64++; + cemu_assert_debug((CACHE_PAGE_SIZE % 32) == 0); + const uint64* ptr = (const uint64*)mem; + const uint64* end = ptr + (CACHE_PAGE_SIZE / sizeof(uint64)); + + uint64 h0 = 0; + uint64 h1 = 0; + uint64 h2 = 0; + uint64 h3 = 0; + while (ptr < end) + { + h0 = std::rotr(h0, 7); + h1 = std::rotr(h1, 7); + h2 = std::rotr(h2, 7); + h3 = std::rotr(h3, 7); + + h0 += ptr[0] * k0; + h1 += ptr[1] * k1; + h2 += ptr[2] * k2; + h3 += ptr[3] * k3; + ptr += 4; } - return h; + + return h0 + h1 + h2 + h3; } // flag page as having streamout data, also write streamout signatures to page memory