VNC-156 Integrate libcpuid for enhanced CPU feature detection

This commit is contained in:
El 2025-05-25 01:43:30 +05:00
parent 209702638b
commit 0104fef44e
No known key found for this signature in database
GPG Key ID: EB3F4C9EA29CDE59
3 changed files with 92 additions and 8 deletions

View File

@ -132,6 +132,8 @@ endif ()
find_package(PkgConfig REQUIRED)
pkg_check_modules(FFMPEG REQUIRED libavcodec libavformat libavutil libswscale)
pkg_check_modules(CPUID REQUIRED libcpuid)
find_package(TBB)
if (TBB_FOUND)
set(RFB_LIBRARIES ${RFB_LIBRARIES} tbb)
@ -150,9 +152,10 @@ target_include_directories(rfb PRIVATE
${CMAKE_SOURCE_DIR}/third_party/tinyxml2
${FFMPEG_INCLUDE_DIRS}
${TBB_INCLUDE_DIRS}
${CPUID_INCLUDE_DIRS}
)
target_link_libraries(rfb PUBLIC ${RFB_LIBRARIES} tinyxml2_objs)
target_link_libraries(rfb PUBLIC ${RFB_LIBRARIES} tinyxml2_objs ${TBB_LIBRARIES} ${CPUID_LIBRARIES})
if (UNIX)
libtool_create_control_file(rfb)

View File

@ -16,10 +16,12 @@
* USA.
*/
#include <stdint.h>
#include "cpuid.h"
#include <cstdint>
#include "LogWriter.h"
static uint32_t cpuid[4] = { 0 };
static uint32_t extcpuid[4] = { 0 };
static uint32_t cpuid[4] = {};
static uint32_t extcpuid[4] = {};
static void getcpuid() {
if (cpuid[0])
@ -68,3 +70,28 @@ bool supportsAVX512f() {
}
}; // namespace rfb
namespace cpu_info {
static rfb::LogWriter log("CpuFeatures");
inline CpuFeatures::CpuFeatures()
{
if (!cpuid_present())
{
log.error("CPU does not support CPUID.");
return;
}
cpu_raw_data_t raw{};
if (cpuid_get_raw_data(&raw) < 0)
{
log.error("Cannot get CPUID raw data.");
return;
}
if (cpu_identify(&raw, &data) < 0)
{
log.error("Cannot identify CPU.");
}
}
} // namespace cpu_info

View File

@ -19,10 +19,64 @@
#ifndef __RFB_CPUID_H__
#define __RFB_CPUID_H__
namespace rfb {
#include <algorithm>
#include <libcpuid/libcpuid.h>
namespace cpu_info {
//using namespace cpu_features;
//static const X86Info info = GetX86Info();
// static const X86Microarchitecture uarch = GetX86Microarchitecture(&info);
//static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB;
bool supportsSSE2();
bool supportsAVX512f();
class CpuFeatures {
cpu_id_t data{};
CpuFeatures();
public:
CpuFeatures(const CpuFeatures &) = delete;
CpuFeatures &operator=(const CpuFeatures &) = delete;
CpuFeatures(CpuFeatures &&) = delete;
CpuFeatures &operator=(CpuFeatures &&) = delete;
static CpuFeatures &get()
{
static CpuFeatures instance{};
return instance;
}
[[nodiscard]] bool has_sse2() const { return data.flags[CPU_FEATURE_SSE2]; }
[[nodiscard]] bool has_sse4_1() const { return data.flags[CPU_FEATURE_SSE4_1]; }
[[nodiscard]] bool has_sse4_2() const { return data.flags[CPU_FEATURE_SSE4_2]; }
[[nodiscard]] bool has_sse4a() const { return data.flags[CPU_FEATURE_SSE4A]; }
[[nodiscard]] bool has_avx() const { return data.flags[CPU_FEATURE_AVX]; }
[[nodiscard]] bool has_avx2() const { return data.flags[CPU_FEATURE_AVX2]; }
[[nodiscard]] bool has_avx512f() const { return data.flags[CPU_FEATURE_AVX512F]; }
[[nodiscard]] bool has_smt() const { return get_total_cpu_count() > get_cores_count(); }
[[nodiscard]] uint16_t get_total_cpu_count() const { return std::max(1, data.total_logical_cpus); }
[[nodiscard]] uint16_t get_cores_count() const { return std::max(1, data.num_cores); }
};
inline static const bool has_sse2 = CpuFeatures::get().has_sse2();
inline static const bool has_sse4_1 = CpuFeatures::get().has_sse4_1();
inline static const bool has_sse4_2 = CpuFeatures::get().has_sse4_2();
inline static const bool has_sse4a = CpuFeatures::get().has_sse4a();
inline static const bool has_avx = CpuFeatures::get().has_avx();
inline static const bool has_avx2 = CpuFeatures::get().has_avx2();
inline static const bool has_avx512f = CpuFeatures::get().has_avx512f();
inline static const uint16_t cores_count = CpuFeatures::get().get_cores_count();
inline static const uint16_t total_cpu_count = CpuFeatures::get().get_total_cpu_count();
}; // namespace cpu_info
#endif