针对最近的Intel CPU(不是一般的x86,而是只针对Intel),我使用 EAX=0Bh
cpuid
leaf。有关当前套接字/封装中核心的信息,请参见维基百科。在多套接字系统上,这可能是系统范围内物理/逻辑核心数量的一半或四分之一。Intel发布了一篇关于枚举CPU并提供有关多套接字系统的检查细节的白皮书。此代码不执行该操作,它只检查一个子叶(ECX=1)。
int main()
{
unsigned int eax=11,ebx=0,ecx=1,edx=0;
asm volatile("cpuid"
: "=a" (eax),
"=b" (ebx),
"=c" (ecx),
"=d" (edx)
: "0" (eax), "2" (ecx)
: );
printf("Cores: %d\nThreads: %d\nActual thread: %d\n",eax,ebx,edx);
}
输出:
Cores: 4
Threads: 8
Actual thread: 1
或者更简洁地说:
#include <stdio.h>
int main()
{
unsigned int ncores=0,nthreads=0,ht=0;
asm volatile("cpuid": "=a" (ncores), "=b" (nthreads) : "a" (0xb), "c" (0x1) : );
ht=(ncores!=nthreads);
printf("Cores: %d\nThreads: %d\nHyperThreading: %s\n",ncores,nthreads,ht?"Yes":"No");
return 0;
}
输出:
Cores: 4
Threads: 8
HyperThreading: Yes
(system("exit `nproc`") >> 8)
...即使是busybox也有一个内部的nproc,所以在任何Linux上都应该可以正常工作(例如,我的路由器固件...)。移位操作是必需的,因为sh
退出码嵌入了一个尾随的空字节,以便进行字符串处理。 - l.k