3
0
Fork 0
forked from suyu/suyu

Merge pull request #9231 from goldenx86/corecount

Add CPU core count to log files
This commit is contained in:
Mai 2022-11-12 03:19:26 +00:00 committed by GitHub
commit 7dfe35eca6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 3 deletions

View file

@ -4,14 +4,27 @@
#include <array> #include <array>
#include <cstring> #include <cstring>
#include <fstream>
#include <iterator> #include <iterator>
#include <optional>
#include <string_view> #include <string_view>
#include <thread>
#include <vector>
#include "common/bit_util.h" #include "common/bit_util.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h"
#include "common/x64/cpu_detect.h" #include "common/x64/cpu_detect.h"
#ifdef _WIN32
#include <windows.h>
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#include <intrin.h> #include <intrin.h>
static inline u64 xgetbv(u32 index) {
return _xgetbv(index);
}
#else #else
#if defined(__DragonFly__) || defined(__FreeBSD__) #if defined(__DragonFly__) || defined(__FreeBSD__)
@ -39,12 +52,11 @@ static inline void __cpuid(int info[4], u32 function_id) {
} }
#define _XCR_XFEATURE_ENABLED_MASK 0 #define _XCR_XFEATURE_ENABLED_MASK 0
static inline u64 _xgetbv(u32 index) { static inline u64 xgetbv(u32 index) {
u32 eax, edx; u32 eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((u64)edx << 32) | eax; return ((u64)edx << 32) | eax;
} }
#endif // _MSC_VER #endif // _MSC_VER
namespace Common { namespace Common {
@ -107,7 +119,7 @@ static CPUCaps Detect() {
// - Is the XSAVE bit set in CPUID? // - Is the XSAVE bit set in CPUID?
// - XGETBV result has the XCR bit set. // - XGETBV result has the XCR bit set.
if (Common::Bit<28>(cpu_id[2]) && Common::Bit<27>(cpu_id[2])) { if (Common::Bit<28>(cpu_id[2]) && Common::Bit<27>(cpu_id[2])) {
if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) { if ((xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) {
caps.avx = true; caps.avx = true;
if (Common::Bit<12>(cpu_id[2])) if (Common::Bit<12>(cpu_id[2]))
caps.fma = true; caps.fma = true;
@ -192,4 +204,45 @@ const CPUCaps& GetCPUCaps() {
return caps; return caps;
} }
std::optional<int> GetProcessorCount() {
#if defined(_WIN32)
// Get the buffer length.
DWORD length = 0;
GetLogicalProcessorInformation(nullptr, &length);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
LOG_ERROR(Frontend, "Failed to query core count.");
return std::nullopt;
}
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(
length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
// Now query the core count.
if (!GetLogicalProcessorInformation(buffer.data(), &length)) {
LOG_ERROR(Frontend, "Failed to query core count.");
return std::nullopt;
}
return static_cast<int>(
std::count_if(buffer.cbegin(), buffer.cend(), [](const auto& proc_info) {
return proc_info.Relationship == RelationProcessorCore;
}));
#elif defined(__unix__)
const int thread_count = std::thread::hardware_concurrency();
std::ifstream smt("/sys/devices/system/cpu/smt/active");
char state = '0';
if (smt) {
smt.read(&state, sizeof(state));
}
switch (state) {
case '0':
return thread_count;
case '1':
return thread_count / 2;
default:
return std::nullopt;
}
#else
// Shame on you
return std::nullopt;
#endif
}
} // namespace Common } // namespace Common

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <optional>
#include <string_view> #include <string_view>
#include "common/common_types.h" #include "common/common_types.h"
@ -74,4 +75,7 @@ struct CPUCaps {
*/ */
const CPUCaps& GetCPUCaps(); const CPUCaps& GetCPUCaps();
/// Detects CPU core count
std::optional<int> GetProcessorCount();
} // namespace Common } // namespace Common

View file

@ -362,6 +362,10 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan
} }
LOG_INFO(Frontend, "Host CPU: {}", cpu_string); LOG_INFO(Frontend, "Host CPU: {}", cpu_string);
#endif #endif
if (std::optional<int> processor_core = Common::GetProcessorCount()) {
LOG_INFO(Frontend, "Host CPU Cores: {}", *processor_core);
}
LOG_INFO(Frontend, "Host CPU Threads: {}", processor_count); LOG_INFO(Frontend, "Host CPU Threads: {}", processor_count);
LOG_INFO(Frontend, "Host OS: {}", PrettyProductName().toStdString()); LOG_INFO(Frontend, "Host OS: {}", PrettyProductName().toStdString());
LOG_INFO(Frontend, "Host RAM: {:.2f} GiB", LOG_INFO(Frontend, "Host RAM: {:.2f} GiB",