我检查了cpuid
文档,发现了两种不同的记录方法来获取缓存行大小:
eax = 0x04, ecx = $cache_level
这样,缓存行的大小$cache_level
将存储EBX[11:0]
在位
eax = 0x80000006
这样,缓存行大小将存储在ECX[7:0]
该位置,并且叶不依赖于缓存级别。
问题:向叶子添加缓存行大小信息的原因是什么0x80000006
,为什么它不取决于缓存级别?我怀疑获取缓存行大小的“正确”方法是eax = 0x04, ecx = $cache_level
。
英特尔和AMD(以及威盛和...)是不同的公司;而且(遗憾的是)没有涉及供应商中立的标准化机构,没有强迫供应商之间理智合作,也没有阻止供应商大肆破坏彼此的形象。
AMD创建“ CPUID,叶子0x80000006”时,他们做了一件容易的事-假定所有缓存的缓存行大小均相同,然后将其放入字段中。
但是(至少在理论上)每个不同的高速缓存都可以具有不同的“行大小”。因此,当英特尔创建“ CPUID,叶0x00000004”时,它们的作用是(理论上)每个不同的缓存都可以报告不同的“行大小”。
正确的方法是使杂乱无章的情况能够解决供应商的混乱情况。特别; 对于AMD CPU,如果可以的话,您希望使用“ CPUID,leaf 0x80000006”;对于Intel CPU(我认为是VIA CPU),如果可以的话,您希望使用“ CPUID,leaf 0x00000004”;对于所有您无法使用的情况(例如,因为CPU太旧而无法支持供应商的方法),您都会陷入另一大麻烦(例如,使用启发式方法和/或使用“ vendor:family:model:stepping”来查找)静态数据库中的信息)。
当然,最重要的是,您必须考虑勘误。这意味着要浏览大约一百个“规范更新”和“ BIOS和内核开发人员指南”,以查找是否/在何处需要“特殊情况下的解决方法”。
注1:如果您只关心高速缓存行大小,则上述所有内容都不太难。但是,您想要的信息越多,获取的信息就越糟(例如,如果您也关心每个缓存的大小,那么您应该会遇到大约10倍的麻烦和10倍的维护负担)。
注2:理想情况下,操作系统应提供“预先清理的CPU信息”;这样一来,只需要将其更新到一个位置即可,这样普通软件就无需处理毫无意义的“供应商差异”,勘误表,丢失的信息或合并的信息;并且CPUID
禁止直接使用该说明(出于方便,正确和安全的原因)。不幸的是,没有现有的操作系统提供此功能。