[*] Optimize thread configurations to be unpacked from the bitmap once at startup and during reconfigure as opposed ad-hoc

This commit is contained in:
Reece Wilson 2023-09-09 17:37:14 +01:00
parent ca2f8fea71
commit 88355932c1
12 changed files with 120 additions and 43 deletions

View File

@ -55,6 +55,8 @@ static void Pump();
static void Init()
{
Aurora::Threading::Primitives::InitCfg();
Aurora::InitProcAddresses();
gRuntimeRunLevel = 1;

View File

@ -356,7 +356,7 @@ namespace Aurora::Threading
AUKN_SYM bool IsWaitOnRecommended()
{
if (gRuntimeConfig.threadingConfig.bPreferEmulatedWakeOnAddress)
if (Primitives::ThrdCfg::gPreferEmulatedWakeOnAddress)
{
return false;
}
@ -590,7 +590,7 @@ namespace Aurora::Threading
}
auto uMaxSwitches = gRuntimeConfig.threadingConfig.uUWPNanosecondEmulationMaxYields;
auto bUWPNanosecondEmulationCheckFirst = gRuntimeConfig.threadingConfig.bUWPNanosecondEmulationCheckFirst;
auto bUWPNanosecondEmulationCheckFirst = Primitives::ThrdCfg::gUWPNanosecondEmulationCheckFirst;
// LockN(<1MS) on a platform without that resolution of yielding... damn
auto uMS = AuNSToMS<AuUInt32>(uRelativeNanoseconds);
@ -875,7 +875,7 @@ namespace Aurora::Threading
}
else
{
if (gRuntimeConfig.threadingConfig.bPreferWaitOnAddressAlwaysSpin)
if (Primitives::ThrdCfg::gPreferWaitOnAddressAlwaysSpin)
{
if (TryWaitOnAddress(pTargetAddress, pCompareAddress, uWordSize))
{
@ -981,7 +981,7 @@ namespace Aurora::Threading
}
else
{
if (gRuntimeConfig.threadingConfig.bPreferWaitOnAddressAlwaysSpin)
if (Primitives::ThrdCfg::gPreferWaitOnAddressAlwaysSpin)
{
if (TryWaitOnAddress(pTargetAddress, pCompareAddress, uWordSize))
{

View File

@ -58,7 +58,7 @@ namespace Aurora::Threading::Primitives
Time::monoabsns2ts(&tspec, uTimeout);
}
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
if (ThrdCfg::gPreferLinuxPrimitivesFutexNoSpin)
{
if (this->TryLockNoSpin())
{
@ -128,7 +128,7 @@ namespace Aurora::Threading::Primitives
bool LinuxConditionMutex::TryLock()
{
if (gRuntimeConfig.threadingConfig.bPreferLinuxCondMutexSpinTryLock)
if (ThrdCfg::gPreferLinuxCondMutexSpinTryLock)
{
return TryLockHeavy();
}
@ -153,7 +153,7 @@ namespace Aurora::Threading::Primitives
void LinuxConditionMutex::Lock()
{
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
if (ThrdCfg::gPreferLinuxPrimitivesFutexNoSpin)
{
if (this->TryLockNoSpin())
{

View File

@ -33,7 +33,7 @@ namespace Aurora::Threading::Primitives
#if defined(AURORA_FORCE_SRW_LOCKS)
return ::TryAcquireSRWLockExclusive(&this->lock_);
#else
if (gRuntimeConfig.threadingConfig.bPreferNtCondMutexSpinTryLock)
if (ThrdCfg::gPreferNtCondMutexSpinTryLock)
{
return TryLockHeavy();
}

View File

@ -65,7 +65,7 @@ namespace Aurora::Threading::Primitives
if (gUseNativeWaitCondvar)
{
// Reverted: 5b495f7fd9495aa55395666e166ac499955215dc
if (gRuntimeConfig.threadingConfig.bPreferNtCondvarModernWinSpin)
if (ThrdCfg::gPreferNtCondvarModernWinSpin)
{
if (!bIOU)
{
@ -87,7 +87,7 @@ namespace Aurora::Threading::Primitives
else
{
// Reverted: 5b495f7fd9495aa55395666e166ac499955215dc
if (gRuntimeConfig.threadingConfig.bPreferNtCondvarOlderWinSpin)
if (ThrdCfg::gPreferNtCondvarOlderWinSpin)
{
if (!bIOU)
{
@ -206,7 +206,7 @@ namespace Aurora::Threading::Primitives
if (gUseNativeWaitCondvar)
{
if (gRuntimeConfig.threadingConfig.bPreferNtCondvarModernWinSpin)
if (ThrdCfg::gPreferNtCondvarModernWinSpin)
{
if (!bIOU)
{
@ -223,7 +223,7 @@ namespace Aurora::Threading::Primitives
}
else
{
if (gRuntimeConfig.threadingConfig.bPreferNtCondvarOlderWinSpin)
if (ThrdCfg::gPreferNtCondvarOlderWinSpin)
{
if (!bIOU)
{

View File

@ -39,7 +39,7 @@ namespace Aurora::Threading::Primitives
bool MutexImpl::TryLock()
{
if (gRuntimeConfig.threadingConfig.bPreferLinuxMutexSpinTryLock)
if (ThrdCfg::gPreferLinuxMutexSpinTryLock)
{
return this->TryLockHeavy();
}
@ -72,7 +72,7 @@ namespace Aurora::Threading::Primitives
AuUInt64 uStart {};
AuUInt64 uEnd {};
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
if (ThrdCfg::gPreferLinuxPrimitivesFutexNoSpin)
{
if (this->TryLockNoSpin())
{

View File

@ -54,7 +54,7 @@ namespace Aurora::Threading::Primitives
bool MutexImpl::TryLock()
{
if (gRuntimeConfig.threadingConfig.bPreferNtMutexSpinTryLock)
if (ThrdCfg::gPreferNtMutexSpinTryLock)
{
return TryLockHeavy();
}

View File

@ -559,7 +559,7 @@ namespace Aurora::Threading::Primitives
template<bool bIsWriteRecursionAllowed>
bool RWLockImpl<bIsWriteRecursionAllowed>::TryLockRead()
{
if (gRuntimeConfig.threadingConfig.bPreferRWLockReadLockSpin &&
if (ThrdCfg::gPreferRWLockReadLockSpin &&
AuAtomicLoad(&this->writersPending_) == 0)
{
return DoTryIf([=]()
@ -587,8 +587,8 @@ namespace Aurora::Threading::Primitives
if constexpr (CheckWrite)
{
if ((AuAtomicLoad(&this->writersPending_)) &&
(iCurState > 0 || gRuntimeConfig.threadingConfig.bAlwaysRWLockWriteBiasOnReadLock) &&
(gRuntimeConfig.threadingConfig.bEnableRWLockWriteBiasOnReadLock))
(iCurState > 0 || ThrdCfg::gAlwaysRWLockWriteBiasOnReadLock) &&
(ThrdCfg::gEnableRWLockWriteBiasOnReadLock))
{
return false;
}

View File

@ -40,7 +40,7 @@ namespace Aurora::Threading::Primitives
bool SemaphoreImpl::TryLock()
{
if (gRuntimeConfig.threadingConfig.bPreferLinuxSemaphoreSpinTryLock)
if (ThrdCfg::gPreferLinuxSemaphoreSpinTryLock)
{
return this->TryLockHeavy();
}
@ -84,7 +84,7 @@ namespace Aurora::Threading::Primitives
Time::monoabsns2ts(&tspec, uEnd);
}
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
if (ThrdCfg::gPreferLinuxPrimitivesFutexNoSpin)
{
if (this->TryLockNoSpin())
{
@ -162,7 +162,7 @@ namespace Aurora::Threading::Primitives
{
AuUInt64 uEnd {};
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
if (ThrdCfg::gPreferLinuxPrimitivesFutexNoSpin)
{
if (this->TryLockNoSpin())
{

View File

@ -59,7 +59,7 @@ namespace Aurora::Threading::Primitives
bool SemaphoreImpl::TryLock()
{
if (gRuntimeConfig.threadingConfig.bPreferNtSemaphoreSpinTryLock)
if (ThrdCfg::gPreferNtSemaphoreSpinTryLock)
{
return TryLockHeavy();
}

View File

@ -30,7 +30,7 @@ namespace Aurora::Threading
{
AuUInt32 uCount {};
if (!gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized)
if (!Primitives::ThrdCfg::gPlatformIsSMPProcessorOptimized)
{
return 0;
}
@ -59,9 +59,13 @@ namespace Aurora::Threading
{
return;
}
ThreadingConfig cpy(*pUpdateConfig);
cpy.bPreferFutexRWLock = Primitives::ThrdCfg::gPreferFutexRWLock;
cpy.bPreferEmulatedWakeOnAddress = Primitives::ThrdCfg::gPreferEmulatedWakeOnAddress;
gRuntimeConfig.threadingConfig = decltype(gRuntimeConfig.threadingConfig)(cpy);
gRuntimeConfig.threadingConfig = decltype(gRuntimeConfig.threadingConfig)(ThreadingConfig(*pUpdateConfig));
Primitives::InitCfg();
Primitives::InitAdaptiveThreshold();
}
@ -74,17 +78,17 @@ namespace Aurora::Threading::Primitives
{
auto uCores = AuHwInfo::GetCPUInfo().uThreads;
gUseFutexRWLock = gRuntimeConfig.threadingConfig.bPreferFutexRWLock &&
gUseFutexRWLock = ThrdCfg::gPreferFutexRWLock &&
IsWaitOnRecommended();
if (uCores == 1)
{
gSpinAdaptiveThreshold = 0;
gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized = false;
ThrdCfg::gPlatformIsSMPProcessorOptimized = false;
return;
}
if (!gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin)
if (!ThrdCfg::gForceEnableAdaptiveSpin)
{
gSpinAdaptiveThreshold = 0;
return;
@ -92,19 +96,19 @@ namespace Aurora::Threading::Primitives
if (uCores >= 16)
{
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt16;
gSpinAdaptiveThreshold = uCores / ThrdCfg::gAdaptiveSpinCUCnt16;
}
else if (uCores >= 8 && gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt8)
else if (uCores >= 8 && ThrdCfg::gAdaptiveSpinCUCnt8)
{
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt8;
gSpinAdaptiveThreshold = uCores / ThrdCfg::gAdaptiveSpinCUCnt8;
}
else if (uCores >= 4 && gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt4)
else if (uCores >= 4 && ThrdCfg::gAdaptiveSpinCUCnt4)
{
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt4;
gSpinAdaptiveThreshold = uCores / ThrdCfg::gAdaptiveSpinCUCnt4;
}
else if (uCores >= 0 && gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt0)
else if (uCores >= 0 && ThrdCfg::gAdaptiveSpinCUCnt0)
{
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt0;
gSpinAdaptiveThreshold = uCores / ThrdCfg::gAdaptiveSpinCUCnt0;
}
else
{
@ -114,26 +118,61 @@ namespace Aurora::Threading::Primitives
void InitAdaptiveThresholdFirstTime()
{
if (!gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin &&
gRuntimeConfig.threadingConfig.bPreferEnableAdaptiveSpin)
if (!ThrdCfg::gForceEnableAdaptiveSpin &&
ThrdCfg::gPreferEnableAdaptiveSpin)
{
#if defined(AURORA_IS_LINUX_DERIVED)
if (gRuntimeConfig.threadingConfig.bPreferLinuxAdaptiveSpin)
if (ThrdCfg::gPreferLinuxAdaptiveSpin)
{
gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin = true;
ThrdCfg::gForceEnableAdaptiveSpin = true;
}
#else
if (AuSwInfo::IsWindows10OrGreater())
{
gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferNewWin32AdaptiveSpin;
ThrdCfg::gForceEnableAdaptiveSpin = ThrdCfg::gPreferNewWin32AdaptiveSpin;
}
else
{
gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferOldWin32AdaptiveSpin;
ThrdCfg::gForceEnableAdaptiveSpin = ThrdCfg::gPreferOldWin32AdaptiveSpin;
}
#endif
}
InitAdaptiveThreshold();
}
void InitCfg()
{
ThrdCfg::gPlatformIsSMPProcessorOptimized = gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized;
ThrdCfg::gEnableAggressiveScheduling = gRuntimeConfig.threadingConfig.bEnableAggressiveScheduling;
ThrdCfg::gEnableAgrSchedulingRatelimit = gRuntimeConfig.threadingConfig.bEnableAgrSchedulingRatelimit;
ThrdCfg::gPreferNtCondvarModernWinSpin = gRuntimeConfig.threadingConfig.bPreferNtCondvarModernWinSpin;
ThrdCfg::gPreferNtCondvarOlderWinSpin = gRuntimeConfig.threadingConfig.bPreferNtCondvarOlderWinSpin;
ThrdCfg::gPreferNtSemaphoreSpinTryLock = gRuntimeConfig.threadingConfig.bPreferNtSemaphoreSpinTryLock;
ThrdCfg::gPreferNtMutexSpinTryLock = gRuntimeConfig.threadingConfig.bPreferNtMutexSpinTryLock;
ThrdCfg::gPreferNtCondMutexSpinTryLock = gRuntimeConfig.threadingConfig.bPreferNtCondMutexSpinTryLock;
ThrdCfg::gPreferLinuxSemaphoreSpinTryLock = gRuntimeConfig.threadingConfig.bPreferLinuxSemaphoreSpinTryLock;
ThrdCfg::gPreferLinuxMutexSpinTryLock = gRuntimeConfig.threadingConfig.bPreferLinuxMutexSpinTryLock;
ThrdCfg::gPreferLinuxCondMutexSpinTryLock = gRuntimeConfig.threadingConfig.bPreferLinuxCondMutexSpinTryLock;
ThrdCfg::gPreferEmulatedWakeOnAddress = gRuntimeConfig.threadingConfig.bPreferEmulatedWakeOnAddress;
ThrdCfg::gPreferWaitOnAddressAlwaysSpin = gRuntimeConfig.threadingConfig.bPreferWaitOnAddressAlwaysSpin;
ThrdCfg::gPreferRWLockReadLockSpin = gRuntimeConfig.threadingConfig.bPreferRWLockReadLockSpin;
ThrdCfg::gUWPNanosecondEmulationCheckFirst = gRuntimeConfig.threadingConfig.bUWPNanosecondEmulationCheckFirst;
ThrdCfg::gUWPNanosecondEmulationMaxYields = gRuntimeConfig.threadingConfig.uUWPNanosecondEmulationMaxYields;
ThrdCfg::gForceEnableAdaptiveSpin = gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin;
ThrdCfg::gPreferEnableAdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferEnableAdaptiveSpin;
ThrdCfg::gPreferLinuxAdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferLinuxAdaptiveSpin;
ThrdCfg::gPreferOldWin32AdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferOldWin32AdaptiveSpin;
ThrdCfg::gPreferNewWin32AdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferNewWin32AdaptiveSpin;
ThrdCfg::gAdaptiveSpinCUCnt0 = gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt0;
ThrdCfg::gAdaptiveSpinCUCnt4 = gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt4;
ThrdCfg::gAdaptiveSpinCUCnt8 = gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt8;
ThrdCfg::gAdaptiveSpinCUCnt16 = gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt16;
ThrdCfg::gPreferFutexRWLock = gRuntimeConfig.threadingConfig.bPreferFutexRWLock;
ThrdCfg::gWinXpThrough7BlazeOptimizerPower = gRuntimeConfig.threadingConfig.bWinXpThrough7BlazeOptimizerPower;
ThrdCfg::gPreferLinuxPrimitivesFutexNoSpin = gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin;
ThrdCfg::gPreferUnixPrimitivesNoSpin = gRuntimeConfig.threadingConfig.bPreferUnixPrimitivesNoSpin;
ThrdCfg::gAlwaysRWLockWriteBiasOnReadLock = gRuntimeConfig.threadingConfig.bAlwaysRWLockWriteBiasOnReadLock;
ThrdCfg::gEnableRWLockWriteBiasOnReadLock = gRuntimeConfig.threadingConfig.bEnableRWLockWriteBiasOnReadLock;
}
}

View File

@ -1,4 +1,4 @@
/***
/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: SMTYield.hpp
@ -17,6 +17,41 @@ namespace Aurora::Threading
namespace Aurora::Threading::Primitives
{
namespace ThrdCfg
{
inline bool gPlatformIsSMPProcessorOptimized {}; // to include or not to include 🤔
inline bool gEnableAggressiveScheduling {};
inline bool gEnableAgrSchedulingRatelimit {};
inline bool gPreferNtCondvarModernWinSpin {};
inline bool gPreferNtCondvarOlderWinSpin {};
inline bool gPreferNtSemaphoreSpinTryLock {};
inline bool gPreferNtMutexSpinTryLock {};
inline bool gPreferNtCondMutexSpinTryLock {};
inline bool gPreferLinuxSemaphoreSpinTryLock {};
inline bool gPreferLinuxMutexSpinTryLock {};
inline bool gPreferLinuxCondMutexSpinTryLock {};
inline bool gPreferEmulatedWakeOnAddress {};
inline bool gPreferWaitOnAddressAlwaysSpin {};
inline bool gPreferRWLockReadLockSpin {};
inline bool gUWPNanosecondEmulationCheckFirst {};
inline AuUInt32 gUWPNanosecondEmulationMaxYields {};
inline bool gForceEnableAdaptiveSpin {};
inline bool gPreferEnableAdaptiveSpin {};
inline bool gPreferLinuxAdaptiveSpin {};
inline bool gPreferOldWin32AdaptiveSpin {};
inline bool gPreferNewWin32AdaptiveSpin {};
inline AuUInt32 gAdaptiveSpinCUCnt0 {};
inline AuUInt32 gAdaptiveSpinCUCnt4 {};
inline AuUInt32 gAdaptiveSpinCUCnt8 {};
inline AuUInt32 gAdaptiveSpinCUCnt16 {};
inline bool gPreferFutexRWLock {};
inline bool gWinXpThrough7BlazeOptimizerPower {};
inline bool gPreferLinuxPrimitivesFutexNoSpin {};
inline bool gPreferUnixPrimitivesNoSpin {};
inline bool gAlwaysRWLockWriteBiasOnReadLock {};
inline bool gEnableRWLockWriteBiasOnReadLock {};
}
inline AuUInt32 gSpinAdaptiveThreshold {};
inline AuUInt32 gSpinAdaptiveCurrentCount {};
@ -24,6 +59,7 @@ namespace Aurora::Threading::Primitives
void InitAdaptiveThreshold();
void InitAdaptiveThresholdFirstTime();
void InitCfg();
static auline void SMPPause()
{
@ -191,7 +227,7 @@ namespace Aurora::Threading::Primitives
template <typename T>
bool auline DoTryIf(T callback)
{
if (gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized)
if (ThrdCfg::gPlatformIsSMPProcessorOptimized)
{
return YieldToSharedCore(gRuntimeConfig.threadingConfig.uSpinLoopPowerA, callback);
}