diff --git a/CMakeLists.txt b/CMakeLists.txt index 30fc4f2490..dd5c005ec5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -726,15 +726,23 @@ if(NOT MSVC) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024") endif() -# _mm_clflushopt support +# intrinsics (_mm_clflushopt and waitpkg) support if(NOT MSVC) check_cxx_compiler_flag(-mclflushopt SUPPORTS_CLFLUSHOPT) + check_cxx_compiler_flag(-mwaitpkg SUPPORTS_WAITPKG) if(SUPPORTS_CLFLUSHOPT) add_compile_definitions(SUPPORTS_CLFLUSHOPT) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mclflushopt") endif() + if(SUPPORTS_WAITPKG) + add_compile_definitions(SUPPORTS_WAITPKG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwaitpkg") + else() + message(WARNING "-mwaitpkg flag is not supported by the compiler") + endif() else() add_compile_definitions(SUPPORTS_CLFLUSHOPT) + add_compile_definitions(SUPPORTS_WAITPKG) endif() # Compiler warning flags diff --git a/shared/source/utilities/cpuintrinsics.cpp b/shared/source/utilities/cpuintrinsics.cpp index 4927080b6a..9f7201e993 100644 --- a/shared/source/utilities/cpuintrinsics.cpp +++ b/shared/source/utilities/cpuintrinsics.cpp @@ -8,8 +8,11 @@ #include "shared/source/utilities/cpuintrinsics.h" #if defined(_WIN32) +#include #include +#pragma intrinsic(__rdtsc) #else +#include #include #endif @@ -42,5 +45,23 @@ void pause() { _mm_pause(); } +unsigned char umwait(unsigned int ctrl, uint64_t counter) { +#ifdef SUPPORTS_WAITPKG + return _umwait(ctrl, counter); +#else + return 0; +#endif +} + +void umonitor(void *a) { +#ifdef SUPPORTS_WAITPKG + _umonitor(a); +#endif +} + +uint64_t rdtsc() { + return __rdtsc(); +} + } // namespace CpuIntrinsics } // namespace NEO diff --git a/shared/source/utilities/cpuintrinsics.h b/shared/source/utilities/cpuintrinsics.h index c550aeecdf..934a43314c 100644 --- a/shared/source/utilities/cpuintrinsics.h +++ b/shared/source/utilities/cpuintrinsics.h @@ -7,6 +7,8 @@ #pragma once +#include + namespace NEO { namespace CpuIntrinsics { @@ -18,5 +20,11 @@ void clFlushOpt(void *ptr); void pause(); +unsigned char umwait(unsigned int ctrl, uint64_t counter); + +void umonitor(void *a); + +uint64_t rdtsc(); + } // namespace CpuIntrinsics } // namespace NEO diff --git a/shared/test/common/utilities/cpuintrinsics.cpp b/shared/test/common/utilities/cpuintrinsics.cpp index ed4dda48df..26c79cd7d4 100644 --- a/shared/test/common/utilities/cpuintrinsics.cpp +++ b/shared/test/common/utilities/cpuintrinsics.cpp @@ -21,11 +21,23 @@ std::atomic clFlushCounter(0u); std::atomic pauseCounter(0u); std::atomic sfenceCounter(0u); +std::atomic lastUmwaitCounter(0u); +std::atomic lastUmwaitControl(0u); +std::atomic umwaitCounter(0u); + +std::atomic lastUmonitorPtr(0u); +std::atomic umonitorCounter(0u); + +std::atomic rdtscCounter(0u); + volatile TagAddressType *pauseAddress = nullptr; TaskCountType pauseValue = 0u; uint32_t pauseOffset = 0u; +uint64_t rdtscRetValue = 0; +unsigned char umwaitRetValue = 0; std::function setupPauseAddress; +std::function controlUmwait; } // namespace CpuIntrinsicsTests namespace NEO { @@ -56,5 +68,26 @@ void pause() { } } +unsigned char umwait(unsigned int ctrl, uint64_t counter) { + CpuIntrinsicsTests::lastUmwaitControl = ctrl; + CpuIntrinsicsTests::lastUmwaitCounter = counter; + CpuIntrinsicsTests::umwaitCounter++; + if (CpuIntrinsicsTests::controlUmwait) { + return CpuIntrinsicsTests::controlUmwait(); + } else { + return CpuIntrinsicsTests::umwaitRetValue; + } +} + +void umonitor(void *a) { + CpuIntrinsicsTests::lastUmonitorPtr = reinterpret_cast(a); + CpuIntrinsicsTests::umonitorCounter++; +} + +uint64_t rdtsc() { + CpuIntrinsicsTests::rdtscCounter++; + return CpuIntrinsicsTests::rdtscRetValue; +} + } // namespace CpuIntrinsics } // namespace NEO