__cpuid 是一个内联汇编函数,用于在 C 和 C++ 代码中获取有关 CPU 信息的指令集扩展。这条指令利用了 x86 和 x86_64 处理器的 CPUID 指令,通过查询处理器支持的功能、型号、制造商等硬件信息,为开发者提供了对 CPU 的低层访问。
使用场景
__cpuid 指令广泛用于需要检测 CPU 支持的功能、优化软件性能、处理硬件相关任务的场景。例如:
检测处理器支持的指令集扩展(如 SSE、AVX、AES-NI 等)来启用或禁用某些优化。
获取 CPU 的型号和特征,以便在不同型号的 CPU 上执行针对性的操作。
硬件虚拟化支持的检测,开发虚拟化软件时可能需要检测 CPU 是否支持虚拟化扩展(如 Intel VT-x)。
函数签名
在不同的编译器和平台中,__cpuid 的实现方式有所不同。以 Visual Studio 为例,它的签名是:
c
复制代码
void __cpuid(int cpuInfo[4], int function_id);
cpuInfo 是一个整型数组,存储 CPU 返回的不同寄存器的值。
function_id 是 CPUID 指令的功能编号,用于指定你希望查询的 CPU 信息。
CPUID 功能编号
CPUID 指令通过不同的功能编号提供不同的信息。例如:
function_id = 0:返回 CPU 支持的最大功能编号以及 CPU 制造商字符串。
function_id = 1:返回 CPU 型号、家族号、步进号、特性标志等信息。
function_id = 7:返回对 AVX2、SHA 等指令集的支持情况。
示例代码
以下是使用 __cpuid 在 C++ 中获取 CPU 信息的一个简单示例:
cpp
复制代码
#include
#include <intrin.h>
int main() {
int cpuInfo[4] = {0};
// 使用 function_id = 0,获取 CPU 的制造商字符串
__cpuid(cpuInfo, 0);
char vendor[13];
memcpy(vendor, &cpuInfo[1], 4); // EBX
memcpy(vendor + 4, &cpuInfo[3], 4); // EDX
memcpy(vendor + 8, &cpuInfo[2], 4); // ECX
vendor[12] = '\0'; // 字符串终止符
std::cout << "CPU Vendor: " << vendor << std::endl;
return 0;
}
返回值解释
cpuInfo[0]、cpuInfo[1]、cpuInfo[2]、cpuInfo[3] 分别对应处理器寄存器 EAX、EBX、ECX 和 EDX 的值。这些寄存器返回的信息根据 function_id 进行解读。例如上面的代码中,通过读取 EBX、EDX 和 ECX 的值,可以得到 CPU 制造商的信息。