逻辑CPU计数返回16而不是4。
逻辑CPU计数返回16而不是4。
我有一台Intel Core i5-2450m (2个物理处理器和4个逻辑处理器),我想找到一种方法来计算AMD和Intel CPU上的逻辑和物理核心数量。
但是,经过一些搜索,我注意到了一些奇怪的事情。我的代码不是返回4个逻辑单元,而是返回了16个。
static int8_t LogicalProcCount(void) { if ( !Hyperthreading ) return 1; uint32_t unused, ebx; CPUID(1, unused, ebx, unused, unused); return (int8_t) ( (ebx >> 16 ) & 0xFF ); }
(Logical CPU count return 16 instead of 4)问题的出现原因是因为CPUID.1:EBX[23:16]
返回的值表示可以分配给物理包中逻辑处理器的最大可寻址ID数。解决方法是使用链接的白皮书中提供的示例代码来计算实际的逻辑CPU数量。
以下是整理的
CPUID.1:EBX[23:16]表示可以分配给物理包中逻辑处理器的最大可寻址ID数。在我的机器上,CPUID.1:EBX[23:16]也返回了16,但它实际上有8个逻辑CPU。这意味着返回的值16与实际的逻辑CPU数量无关。
如果要计算实际的逻辑CPU数量,可以在链接的白皮书中找到示例代码。不幸的是,源链接已经失效,但是可以在该链接提到的白皮书中找到示例代码。
通过使用示例代码,我们可以解决(Logical CPU count return 16 instead of 4)的问题,并获得准确的逻辑CPU数量。
(Logical CPU count return 16 instead of 4)这个问题出现的原因是早期的英特尔处理器(2010年之前)通常可以使用这种代码来计算逻辑CPU数量。即使在2007年左右,这种计数方法在早期的英特尔演示文稿中也被提及。令人非常遗憾的是,即使在2013年的MSDN页面中,这个算法仍然被给出,这个页面是关于__cpuid的,但是这个示例代码自从2008年以来就没有更新过。
2010年初,英特尔推出了Westmere处理器,其APIC id空间中有间隙。因此,这些以及之后的处理器需要更精细的方法来计算它们的核心数。这些处理器都具有x2APIC,并支持cpuid的叶子0xB,可以通过EAX[4:0]告诉你APIC id空间中的间隙,通过EBX告诉你每个级别(包/核心)中存在的逻辑处理器的数量。n.m.提供的链接是权威的,尽管有些枯燥。基本上,你只需要使用EAX=0xB,ECX=1调用cpuid,就可以在EBX中获取返回的每个包中逻辑处理器的正确数量。
关于AMD的问题没有得到回答。因为AMD不支持与英特尔相同的cpuid叶子。我能找到的关于AMD的最新信息(来自2013年)可以在http://developer.amd.com/resources/documentation-articles/articles-whitepapers/processor-and-core-enumeration-using-cpuid/找到。
顺便一提,我在今天更新维基百科关于CPUID的页面时找到了所有这些信息。