结构定义:
cpp
class CPU final
{
public:
static bool has_sse2;
static bool has_sse3;
static bool has_ssse3;
static bool has_sse4_1;
static bool has_sse4_2;
static bool has_avx;
static bool has_avx2;
static bool has_avx512f;
static bool has_sse;
static bool has_aes;
static bool has_sha;
public:
static void cpuid(unsigned int func, unsigned int& eax, unsigned int& ebx, unsigned int& ecx, unsigned int& edx) noexcept;
};
检测实现:
cpp
bool CPU::has_sse = false;
bool CPU::has_sse2 = false;
bool CPU::has_sse3 = false;
bool CPU::has_ssse3 = false;
bool CPU::has_sse4_1 = false;
bool CPU::has_sse4_2 = false;
bool CPU::has_avx = false;
bool CPU::has_avx2 = false;
bool CPU::has_avx512f = false;
bool CPU::has_aes = false;
bool CPU::has_sha = false;
void CPU_detect() noexcept
{
unsigned int eax, ebx, ecx, edx;
// 获取基本最大level
CPU::cpuid(0, eax, ebx, ecx, edx);
unsigned int max_base = eax;
// 检测基本功能1
if (max_base >= 1) {
CPU::cpuid(1, eax, ebx, ecx, edx);
// 根据映射表设置特性标志
CPU::has_sse = (edx & (1 << 25)) != 0; // SSE - EDX[25]
CPU::has_sse2 = (edx & (1 << 26)) != 0; // SSE2 - EDX[26]
CPU::has_sse3 = (ecx & (1 << 0)) != 0; // SSE3 - ECX[0]
CPU::has_aes = (ecx & (1 << 25)) != 0; // AES - ECX[25]
CPU::has_avx = (ecx & (1 << 28)) != 0; // AVX - ECX[28]
}
// 检测扩展功能7
CPU::cpuid(0, eax, ebx, ecx, edx); // 重新获取最大level
if (eax >= 7) {
// EAX=7, ECX=0 for extended features
int cpus[4];
__cpuidex(cpus, 7, 0);
ebx = cpus[1];
// Check bit 5 of EBX for AVX2 support
// GCC -> __builtin_cpu_supports("avx2")
CPU::has_avx2 = (ebx & (1 << 5)) != 0; // AVX2 - EBX[5]
CPU::has_avx512f = (ebx & (1 << 16)) != 0; // AVX512F - EBX[16]
CPU::has_sha = (ebx & (1 << 29)) != 0; // SHA - EBX[29]
}
// 补充检测SSSE3, SSE4.1, SSE4.2(在基本功能1中)
if (max_base >= 1) {
CPU::cpuid(1, eax, ebx, ecx, edx);
CPU::has_ssse3 = (ecx & (1 << 9)) != 0; // SSSE3 - ECX[9]
CPU::has_sse4_1 = (ecx & (1 << 19)) != 0; // SSE4.1 - ECX[19]
CPU::has_sse4_2 = (ecx & (1 << 20)) != 0; // SSE4.2 - ECX[20]
}
}