System: Use cpuinfo for cache line size check

This commit is contained in:
Stenzek 2024-07-02 18:13:42 +10:00
parent a255b5bc75
commit 173a61039c
No known key found for this signature in database
9 changed files with 37 additions and 61 deletions

View file

@ -16,6 +16,7 @@ find_package(ZLIB REQUIRED) # 1.3, but Mac currently doesn't use it.
find_package(PNG 1.6.40 REQUIRED) find_package(PNG 1.6.40 REQUIRED)
find_package(JPEG REQUIRED) # No version because flatpak uses libjpeg-turbo. find_package(JPEG REQUIRED) # No version because flatpak uses libjpeg-turbo.
find_package(Freetype 2.11.1 REQUIRED) find_package(Freetype 2.11.1 REQUIRED)
find_package(cpuinfo REQUIRED)
if(NOT WIN32) if(NOT WIN32)
find_package(CURL REQUIRED) find_package(CURL REQUIRED)

View file

@ -137,7 +137,7 @@ target_precompile_headers(core PRIVATE "pch.h")
target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..") target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..") target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_link_libraries(core PUBLIC Threads::Threads common util ZLIB::ZLIB) target_link_libraries(core PUBLIC Threads::Threads common util ZLIB::ZLIB)
target_link_libraries(core PRIVATE xxhash imgui rapidyaml rcheevos) target_link_libraries(core PRIVATE xxhash imgui rapidyaml rcheevos cpuinfo::cpuinfo)
if(CPU_ARCH_X64) if(CPU_ARCH_X64)
target_compile_definitions(core PUBLIC "ENABLE_RECOMPILER=1" "ENABLE_NEWREC=1" "ENABLE_MMAP_FASTMEM=1") target_compile_definitions(core PUBLIC "ENABLE_RECOMPILER=1" "ENABLE_NEWREC=1" "ENABLE_MMAP_FASTMEM=1")

View file

@ -54,6 +54,7 @@
#include "common/string_util.h" #include "common/string_util.h"
#include "common/threading.h" #include "common/threading.h"
#include "cpuinfo.h"
#include "fmt/chrono.h" #include "fmt/chrono.h"
#include "fmt/format.h" #include "fmt/format.h"
#include "imgui.h" #include "imgui.h"
@ -303,18 +304,43 @@ bool System::Internal::PerformEarlyHardwareChecks(Error* error)
void System::CheckCacheLineSize() void System::CheckCacheLineSize()
{ {
const size_t runtime_cache_line_size = PlatformMisc::GetRuntimeCacheLineSize(); u32 max_line_size = 0;
if (runtime_cache_line_size == 0) if (cpuinfo_initialize())
{
const u32 num_l1is = cpuinfo_get_l1i_caches_count();
const u32 num_l1ds = cpuinfo_get_l1d_caches_count();
const u32 num_l2s = cpuinfo_get_l2_caches_count();
for (u32 i = 0; i < num_l1is; i++)
{
const cpuinfo_cache* cache = cpuinfo_get_l1i_cache(i);
if (cache)
max_line_size = std::max(max_line_size, cache->line_size);
}
for (u32 i = 0; i < num_l1ds; i++)
{
const cpuinfo_cache* cache = cpuinfo_get_l1d_cache(i);
if (cache)
max_line_size = std::max(max_line_size, cache->line_size);
}
for (u32 i = 0; i < num_l2s; i++)
{
const cpuinfo_cache* cache = cpuinfo_get_l2_cache(i);
if (cache)
max_line_size = std::max(max_line_size, cache->line_size);
}
}
if (max_line_size == 0)
{ {
ERROR_LOG("Cannot determine size of cache line. Continuing with expectation of {} byte lines.", ERROR_LOG("Cannot determine size of cache line. Continuing with expectation of {} byte lines.",
runtime_cache_line_size); HOST_CACHE_LINE_SIZE);
} }
else if (HOST_CACHE_LINE_SIZE != runtime_cache_line_size) else if (HOST_CACHE_LINE_SIZE != max_line_size)
{ {
// Not fatal, but does have performance implications. // Not fatal, but does have performance implications.
WARNING_LOG( WARNING_LOG(
"Cache line size mismatch. This build was compiled with {} byte lines, but the system has {} byte lines.", "Cache line size mismatch. This build was compiled with {} byte lines, but the system has {} byte lines.",
HOST_CACHE_LINE_SIZE, runtime_cache_line_size); HOST_CACHE_LINE_SIZE, max_line_size);
} }
} }

View file

@ -207,7 +207,7 @@ if(WIN32)
) )
#set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations") #set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations")
set(DEPS_TO_COPY freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll SDL2.dll shaderc_shared.dll spirv-cross-c-shared.dll zlib1.dll zstd.dll) set(DEPS_TO_COPY cpuinfo.dll freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll SDL2.dll shaderc_shared.dll spirv-cross-c-shared.dll zlib1.dll zstd.dll)
foreach(DEP ${DEPS_TO_COPY}) foreach(DEP ${DEPS_TO_COPY})
list(APPEND DEP_BINS "${CMAKE_PREFIX_PATH}/bin/${DEP}") list(APPEND DEP_BINS "${CMAKE_PREFIX_PATH}/bin/${DEP}")
endforeach() endforeach()

View file

@ -15,9 +15,6 @@ void ResumeScreensaver();
/// Returns the size of pages for the current host. /// Returns the size of pages for the current host.
size_t GetRuntimePageSize(); size_t GetRuntimePageSize();
/// Returns the size of a cache line for the current host.
size_t GetRuntimeCacheLineSize();
/// Abstracts platform-specific code for asynchronously playing a sound. /// Abstracts platform-specific code for asynchronously playing a sound.
/// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound. /// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound.
bool PlaySoundAsync(const char* path); bool PlaySoundAsync(const char* path);

View file

@ -93,11 +93,6 @@ size_t PlatformMisc::GetRuntimePageSize()
return sysctlbyname<u32>("hw.pagesize").value_or(0); return sysctlbyname<u32>("hw.pagesize").value_or(0);
} }
size_t PlatformMisc::GetRuntimeCacheLineSize()
{
return static_cast<size_t>(std::max<s64>(sysctlbyname<s64>("hw.cachelinesize").value_or(0), 0));
}
bool PlatformMisc::PlaySoundAsync(const char* path) bool PlatformMisc::PlaySoundAsync(const char* path)
{ {
NSString* nspath = [[NSString alloc] initWithUTF8String:path]; NSString* nspath = [[NSString alloc] initWithUTF8String:path];

View file

@ -132,28 +132,6 @@ size_t PlatformMisc::GetRuntimePageSize()
return (res > 0) ? static_cast<size_t>(res) : 0; return (res > 0) ? static_cast<size_t>(res) : 0;
} }
size_t PlatformMisc::GetRuntimeCacheLineSize()
{
int l1i = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
int l1d = sysconf(_SC_LEVEL1_ICACHE_LINESIZE);
int res = (l1i > l1d) ? l1i : l1d;
for (int index = 0; index < 16; index++)
{
char buf[128];
snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu0/cache/index%d/coherency_line_size", index);
std::FILE* fp = std::fopen(buf, "rb");
if (!fp)
break;
std::fread(buf, sizeof(buf), 1, fp);
std::fclose(fp);
int val = std::atoi(buf);
res = (val > res) ? val : res;
}
return (res > 0) ? static_cast<size_t>(res) : 0;
}
bool PlatformMisc::PlaySoundAsync(const char* path) bool PlatformMisc::PlaySoundAsync(const char* path)
{ {
#ifdef __linux__ #ifdef __linux__

View file

@ -85,28 +85,6 @@ size_t PlatformMisc::GetRuntimePageSize()
return si.dwPageSize; return si.dwPageSize;
} }
size_t PlatformMisc::GetRuntimeCacheLineSize()
{
DWORD size = 0;
if (!GetLogicalProcessorInformation(nullptr, &size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return 0;
std::unique_ptr<SYSTEM_LOGICAL_PROCESSOR_INFORMATION[]> lpi =
std::make_unique<SYSTEM_LOGICAL_PROCESSOR_INFORMATION[]>(
(size + (sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) - 1)) / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
if (!GetLogicalProcessorInformation(lpi.get(), &size))
return 0;
u32 max_line_size = 0;
for (u32 i = 0; i < size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); i++)
{
if (lpi[i].Relationship == RelationCache)
max_line_size = std::max<u32>(max_line_size, lpi[i].Cache.LineSize);
}
return max_line_size;
}
bool PlatformMisc::PlaySoundAsync(const char* path) bool PlatformMisc::PlaySoundAsync(const char* path)
{ {
const std::wstring wpath(FileSystem::GetWin32Path(path)); const std::wstring wpath(FileSystem::GetWin32Path(path));

View file

@ -4,7 +4,7 @@
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);SOUNDTOUCH_FLOAT_SAMPLES;SOUNDTOUCH_ALLOW_SSE;ST_NO_EXCEPTION_HANDLING=1;ENABLE_VULKAN=1</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);SOUNDTOUCH_FLOAT_SAMPLES;SOUNDTOUCH_ALLOW_SSE;ST_NO_EXCEPTION_HANDLING=1;CPUINFO_SHARED=1;ENABLE_VULKAN=1</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'!='ARM64'">%(PreprocessorDefinitions);ENABLE_OPENGL=1</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Platform)'!='ARM64'">%(PreprocessorDefinitions);ENABLE_OPENGL=1</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='ARM64'">%(PreprocessorDefinitions);SOUNDTOUCH_USE_NEON</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Platform)'=='ARM64'">%(PreprocessorDefinitions);SOUNDTOUCH_USE_NEON</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)dep\xxhash\include;$(SolutionDir)dep\freesurround\include;$(SolutionDir)dep\kissfft\include;$(SolutionDir)dep\soundtouch\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\libchdr\include;$(SolutionDir)dep\cubeb\include;$(SolutionDir)dep\d3d12ma\include;$(SolutionDir)dep\vulkan\include</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)dep\xxhash\include;$(SolutionDir)dep\freesurround\include;$(SolutionDir)dep\kissfft\include;$(SolutionDir)dep\soundtouch\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\libchdr\include;$(SolutionDir)dep\cubeb\include;$(SolutionDir)dep\d3d12ma\include;$(SolutionDir)dep\vulkan\include</AdditionalIncludeDirectories>
@ -27,10 +27,11 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DepsIncludeDir)SDL2</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DepsIncludeDir)SDL2</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>%(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;zlib.lib;zstd.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);cpuinfo.lib;freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;zlib.lib;zstd.lib</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<DepsDLLs Include="$(DepsBinDir)cpuinfo.dll" />
<DepsDLLs Include="$(DepsBinDir)freetype.dll" /> <DepsDLLs Include="$(DepsBinDir)freetype.dll" />
<DepsDLLs Include="$(DepsBinDir)harfbuzz.dll" /> <DepsDLLs Include="$(DepsBinDir)harfbuzz.dll" />
<DepsDLLs Include="$(DepsBinDir)libjpeg.dll" /> <DepsDLLs Include="$(DepsBinDir)libjpeg.dll" />