From fab7bd48c5ce1d59b08ba00c9a7ece013c843cb6 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 30 Aug 2021 20:31:40 +0200 Subject: [PATCH] Optimize atomic and interlocked memory operations on Win32Platform (Windows and Xbox) by inlining --- .../Engine/Platform/Win32/Win32Platform.cpp | 60 +----------------- Source/Engine/Platform/Win32/Win32Platform.h | 61 +++++++++++++++---- 2 files changed, 52 insertions(+), 69 deletions(-) diff --git a/Source/Engine/Platform/Win32/Win32Platform.cpp b/Source/Engine/Platform/Win32/Win32Platform.cpp index 38564cceb..14f370dce 100644 --- a/Source/Engine/Platform/Win32/Win32Platform.cpp +++ b/Source/Engine/Platform/Win32/Win32Platform.cpp @@ -20,6 +20,8 @@ #include #pragma comment(lib, "Iphlpapi.lib") +static_assert(sizeof(int32) == sizeof(long), "Invalid long size for Interlocked and Atomic operations in Win32Platform."); + namespace { Guid DeviceId; @@ -239,59 +241,6 @@ void Win32Platform::MemoryBarrier() #endif } -int64 Win32Platform::InterlockedExchange(int64 volatile* dst, int64 exchange) -{ - return InterlockedExchange64(dst, exchange); -} - -int32 Win32Platform::InterlockedCompareExchange(int32 volatile* dst, int32 exchange, int32 comperand) -{ - static_assert(sizeof(int32) == sizeof(LONG), "Invalid LONG size."); - return _InterlockedCompareExchange((LONG volatile*)dst, exchange, comperand); -} - -int64 Win32Platform::InterlockedCompareExchange(int64 volatile* dst, int64 exchange, int64 comperand) -{ - return InterlockedCompareExchange64(dst, exchange, comperand); -} - -int64 Win32Platform::InterlockedIncrement(int64 volatile* dst) -{ - return InterlockedIncrement64(dst); -} - -int64 Win32Platform::InterlockedDecrement(int64 volatile* dst) -{ - return InterlockedDecrement64(dst); -} - -int64 Win32Platform::InterlockedAdd(int64 volatile* dst, int64 value) -{ - return InterlockedExchangeAdd64(dst, value); -} - -int32 Win32Platform::AtomicRead(int32 volatile* dst) -{ - static_assert(sizeof(int32) == sizeof(LONG), "Invalid LONG size."); - return _InterlockedCompareExchange((LONG volatile*)dst, 0, 0); -} - -int64 Win32Platform::AtomicRead(int64 volatile* dst) -{ - return InterlockedCompareExchange64(dst, 0, 0); -} - -void Win32Platform::AtomicStore(int32 volatile* dst, int32 value) -{ - static_assert(sizeof(int32) == sizeof(LONG), "Invalid LONG size."); - _InterlockedExchange((LONG volatile*)dst, value); -} - -void Win32Platform::AtomicStore(int64 volatile* dst, int64 value) -{ - InterlockedExchange64(dst, value); -} - void Win32Platform::Prefetch(void const* ptr) { _mm_prefetch((char const*)ptr, _MM_HINT_T0); @@ -387,11 +336,6 @@ uint64 Win32Platform::GetCurrentProcessId() return ::GetCurrentProcessId(); } -uint64 Win32Platform::GetCurrentThreadID() -{ - return ::GetCurrentThreadId(); -} - void Win32Platform::SetThreadPriority(ThreadPriority priority) { int32 winPriority; diff --git a/Source/Engine/Platform/Win32/Win32Platform.h b/Source/Engine/Platform/Win32/Win32Platform.h index 02a7d4045..4ed5dd616 100644 --- a/Source/Engine/Platform/Win32/Win32Platform.h +++ b/Source/Engine/Platform/Win32/Win32Platform.h @@ -5,6 +5,12 @@ #if PLATFORM_WIN32 #include "Engine/Platform/Base/PlatformBase.h" +#if _MSC_VER <= 1900 +#include +#else +#include +#endif +extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); /// /// The Win32 platform implementation and application management utilities. @@ -17,16 +23,46 @@ public: static bool Init(); static void Exit(); static void MemoryBarrier(); - static int64 InterlockedExchange(int64 volatile* dst, int64 exchange); - static int32 InterlockedCompareExchange(int32 volatile* dst, int32 exchange, int32 comperand); - static int64 InterlockedCompareExchange(int64 volatile* dst, int64 exchange, int64 comperand); - static int64 InterlockedIncrement(int64 volatile* dst); - static int64 InterlockedDecrement(int64 volatile* dst); - static int64 InterlockedAdd(int64 volatile* dst, int64 value); - static int32 AtomicRead(int32 volatile* dst); - static int64 AtomicRead(int64 volatile* dst); - static void AtomicStore(int32 volatile* dst, int32 value); - static void AtomicStore(int64 volatile* dst, int64 value); + static int64 InterlockedExchange(int64 volatile* dst, int64 exchange) + { + return _InterlockedExchange64(dst, exchange); + } + static int32 InterlockedCompareExchange(int32 volatile* dst, int32 exchange, int32 comperand) + { + return _InterlockedCompareExchange((long volatile*)dst, exchange, comperand); + } + static int64 InterlockedCompareExchange(int64 volatile* dst, int64 exchange, int64 comperand) + { + return _InterlockedCompareExchange64(dst, exchange, comperand); + } + static int64 InterlockedIncrement(int64 volatile* dst) + { + return _InterlockedExchangeAdd64(dst, 1) + 1; + } + static int64 InterlockedDecrement(int64 volatile* dst) + { + return _InterlockedExchangeAdd64(dst, -1) - 1; + } + static int64 InterlockedAdd(int64 volatile* dst, int64 value) + { + return _InterlockedExchangeAdd64(dst, value); + } + static int32 AtomicRead(int32 volatile* dst) + { + return (int32)_InterlockedCompareExchange((long volatile*)dst, 0, 0); + } + static int64 AtomicRead(int64 volatile* dst) + { + return _InterlockedCompareExchange64(dst, 0, 0); + } + static void AtomicStore(int32 volatile* dst, int32 value) + { + _InterlockedExchange((long volatile*)dst, value); + } + static void AtomicStore(int64 volatile* dst, int64 value) + { + _InterlockedExchange64(dst, value); + } static void Prefetch(void const* ptr); static void* Allocate(uint64 size, uint64 alignment); static void Free(void* ptr); @@ -38,7 +74,10 @@ public: static MemoryStats GetMemoryStats(); static ProcessMemoryStats GetProcessMemoryStats(); static uint64 GetCurrentProcessId(); - static uint64 GetCurrentThreadID(); + static uint64 GetCurrentThreadID() + { + return GetCurrentThreadId(); + } static void SetThreadPriority(ThreadPriority priority); static void SetThreadAffinityMask(uint64 affinityMask); static void Sleep(int32 milliseconds);