From 23e580f1b4a0a5eb47fcd5aefcdb12ae2a8aad5f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 28 Apr 2022 08:41:16 +0200 Subject: [PATCH] Long live qYieldCpu()! This is a small wrapper around PAUSE (x86) (and, eventually, YIELD (ARM) and whatever MIPS and Sparc have for this purpose) instructions to improve the performance of tight CAS loops. Pick-to: 6.3 Change-Id: I51e58484c7f02fdbdc491fd1f4a2e9a34f7c2cd0 Reviewed-by: Qt CI Bot Reviewed-by: Sona Kurazyan Reviewed-by: Thiago Macieira --- src/corelib/global/qsimd_p.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/corelib/global/qsimd_p.h b/src/corelib/global/qsimd_p.h index b8e3197eca..8f71710a60 100644 --- a/src/corelib/global/qsimd_p.h +++ b/src/corelib/global/qsimd_p.h @@ -394,6 +394,35 @@ static inline uint64_t qCpuFeatures() #define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature) \ || ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature)) +/* + Small wrapper around x86's PAUSE instruction. + + This is completely different from QThread::yieldCurrentThread(), which is + an OS-level operation that takes the whole thread off the CPU. + + This is just preventing one SMT thread from filling a core's pipeline with + speculated further loop iterations (which need to be expensively flushed on + final success) when it could just give those pipeline slots to a second SMT + thread that can do something useful with the core, such as unblocking this + SMT thread :) + + So, instead of + + while (!condition) + ; + + it's better to use + + while (!condition) + qYieldCpu(); +*/ +static inline void qYieldCpu() +{ +#if defined(Q_PROCESSOR_X86) + _mm_pause(); +#endif +} + #ifdef __cplusplus } // extern "C"