From c306c12763782700e659760ecbb37ea1bdad25dd Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Sun, 30 Jul 2023 09:34:39 +0100 Subject: [PATCH] [*] Improve WakeOnAddress by hash binning by kDefaultWaitPerProcess instead the previous iteration before BST or HashTree lookup --- Source/Threading/AuWakeOnAddress.cpp | 39 +++++++++++++++++++++++----- Source/Threading/AuWakeOnAddress.hpp | 14 ++++++++-- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/Source/Threading/AuWakeOnAddress.cpp b/Source/Threading/AuWakeOnAddress.cpp index 064308cf..88e8ae0d 100644 --- a/Source/Threading/AuWakeOnAddress.cpp +++ b/Source/Threading/AuWakeOnAddress.cpp @@ -183,11 +183,18 @@ namespace Aurora::Threading bool WaitEntry::TryWakeNoLockNoReallyNoLock(const void *pAddress) { + #if 0 if (AuReinterpretCast(this->pAddress) > AuReinterpretCast(pAddress) || AuReinterpretCast(this->pAddress) + this->uSize <= AuReinterpretCast(pAddress)) { return false; } + #else + if (this->pAddress != pAddress) + { + return false; + } + #endif this->uAtomic = 0; this->variable.Signal(); @@ -196,11 +203,18 @@ namespace Aurora::Threading bool WaitEntry::TryWakeNoLock(const void *pAddress) { + #if 0 if (AuReinterpretCast(this->pAddress) > AuReinterpretCast(pAddress) || AuReinterpretCast(this->pAddress) + this->uSize <= AuReinterpretCast(pAddress)) { return false; } + #else + if (this->pAddress != pAddress) + { + return false; + } + #endif AU_LOCK_GUARD(this->mutex); this->uAtomic = 0; @@ -238,7 +252,7 @@ namespace Aurora::Threading } } - WaitEntry *ProcessWaitContainer::WaitBufferFrom(void *pAddress, AuUInt8 uSize) + WaitEntry *ProcessWaitNodeContainer::WaitBufferFrom(void *pAddress, AuUInt8 uSize) { #if defined(HACK_NO_INVALID_ACCESS_LEAK_SHARED_REF_ON_DESTROYED_THREAD) auto pReturn = tlsWaitEntry.get(); @@ -271,7 +285,7 @@ namespace Aurora::Threading } template - bool ProcessWaitContainer::IterateWake(T callback) + bool ProcessWaitNodeContainer::IterateWake(T callback) { bool bRetStatus { true }; @@ -324,16 +338,27 @@ namespace Aurora::Threading return bRetStatus; } - void ProcessWaitContainer::Lock() + void ProcessWaitNodeContainer::Lock() { DoSpinLockOnVar(&this->uAtomic); } - void ProcessWaitContainer::Unlock() + void ProcessWaitNodeContainer::Unlock() { this->uAtomic = 0; } - + + WaitEntry *ProcessWaitContainer::WaitBufferFrom(void *pAddress, AuUInt8 uSize) + { + return this->list[AuHashCode(pAddress) % AuArraySize(this->list)].WaitBufferFrom(pAddress, uSize); + } + + template + bool ProcessWaitContainer::IterateWake(void *pAddress, T callback) + { + return this->list[AuHashCode(pAddress) % AuArraySize(this->list)].IterateWake(callback); + } + AUKN_SYM bool IsWaitOnRecommended() { #if defined(AURORA_IS_MODERNNT_DERIVED) @@ -810,7 +835,7 @@ namespace Aurora::Threading } else { - (void)gProcessWaitables.IterateWake([&](WaitEntry &entry) -> AuPair + (void)gProcessWaitables.IterateWake(pTargetAddress, [&](WaitEntry &entry) -> AuPair { if (!uNMaximumThreads) { @@ -843,7 +868,7 @@ namespace Aurora::Threading } else { - (void)gProcessWaitables.IterateWake([&](WaitEntry &entry) -> AuPair + (void)gProcessWaitables.IterateWake(pTargetAddress, [&](WaitEntry &entry) -> AuPair { return AuMakePair(true, entry.TryWakeNoLockNoReallyNoLock(pTargetAddress)); }); diff --git a/Source/Threading/AuWakeOnAddress.hpp b/Source/Threading/AuWakeOnAddress.hpp index 108efd84..ec8f8f8c 100644 --- a/Source/Threading/AuWakeOnAddress.hpp +++ b/Source/Threading/AuWakeOnAddress.hpp @@ -12,7 +12,7 @@ namespace Aurora::Threading { - static const auto kDefaultWaitPerProcess = 12; + static const auto kDefaultWaitPerProcess = 64; struct WaitState; @@ -71,7 +71,7 @@ namespace Aurora::Threading WaitEntry *pTail {}; }; - struct ProcessWaitContainer + struct ProcessWaitNodeContainer { AuUInt32 uAtomic {}; #if defined(WOA_ENABLE_OLD_SHORT_LIST) @@ -88,4 +88,14 @@ namespace Aurora::Threading void Unlock(); }; + + struct ProcessWaitContainer + { + ProcessWaitNodeContainer list[kDefaultWaitPerProcess]; + + WaitEntry *WaitBufferFrom(void *pAddress, AuUInt8 uSize); + + template + bool IterateWake(void *pAddress, T callback); + }; } \ No newline at end of file