From 40a4eb90af16e5fcdebc0a9126c113c9a7a89fd1 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 14 Sep 2023 17:23:02 -0700 Subject: [PATCH] FEXCore: Disable Enhanced REP MOVSB if TSO is enabled Hades and the vcruntime hits this very hard in memmove. `86.56% [JIT] tid 458574 [.] JIT_0x18000c375_0x7fffc94790c8` ```asm 0x00007fffc94790f8: ldaprb w3, [x2] 0x00007fffc94790fc: stlrb w3, [x1] 0x00007fffc9479100: add x1, x1, #0x1 0x00007fffc9479104: add x2, x2, #0x1 0x00007fffc9479108: sub x0, x0, #0x1 0x00007fffc947910c: cbnz x0, 0x7fffc94790f8 ``` This performance is terrible because Cortex's LRCPC performance is bottom-tier. Work around the performance issue by forcing things to do larger moves with vector moves instead. --- FEXCore/Source/Interface/Context/Context.h | 14 ++++++++++++++ FEXCore/Source/Interface/Core/CPUID.cpp | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/FEXCore/Source/Interface/Context/Context.h b/FEXCore/Source/Interface/Context/Context.h index 45957895f..432b57f45 100644 --- a/FEXCore/Source/Interface/Context/Context.h +++ b/FEXCore/Source/Interface/Context/Context.h @@ -378,6 +378,20 @@ namespace FEXCore::Context { UpdateAtomicTSOEmulationConfig(); } + // Returns if Software TSO emulation is required. + // NOTE: This doesn't necessary return if Atomic-based TSO is currently enabled. + // This will still return true if on a single thread and TSO is currently disabled. + // + // This is to ensure that if early initialization checks CPU features and TSO /could/ be enabled, that + // we return consistent results. + // + // To check if Atomic TSO is currently enabled in the JIT, use `IsAtomicTSOEnabled` instead. + bool SoftwareTSORequired() const { + if (SupportsHardwareTSO) return false; + + return Config.TSOEnabled; + } + void EnableExitOnHLT() override { ExitOnHLT = true; } bool ExitOnHLTEnabled() const { return ExitOnHLT; } diff --git a/FEXCore/Source/Interface/Core/CPUID.cpp b/FEXCore/Source/Interface/Core/CPUID.cpp index 6899a1a55..85aa941e0 100644 --- a/FEXCore/Source/Interface/Core/CPUID.cpp +++ b/FEXCore/Source/Interface/Core/CPUID.cpp @@ -618,6 +618,11 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_06h(uint32_t Leaf) { FEXCore::CPUID::FunctionResults CPUIDEmu::Function_07h(uint32_t Leaf) { FEXCore::CPUID::FunctionResults Res{}; if (Leaf == 0) { + // Disable Enhanced REP MOVS when TSO is enabled. + // vcruntime140 memmove will use `rep movsb` in this case which completely destroys perf in Hades(appId 1145360) + // This is due to LRCPC performance on Cortex being abysmal. + const uint32_t SupportsEnhancedREPMOVS = CTX->SoftwareTSORequired() ? 0 : 1; + // Number of subfunctions Res.eax = 0x0; Res.ebx = @@ -630,7 +635,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_07h(uint32_t Leaf) { (1 << 6) | // FPU data pointer updated only on exception (1 << 7) | // SMEP support (SupportsAVX() << 8) | // BMI2 - (1 << 9) | // Enhanced REP MOVSB/STOSB + (SupportsEnhancedREPMOVS << 9) | // Enhanced REP MOVSB/STOSB (1 << 10) | // INVPCID for system software control of process-context (0 << 11) | // Restricted transactional memory (0 << 12) | // Intel resource directory technology Monitoring