我在准备汇编程序x86项目时遇到了一个问题,该程序的主题是编写一个获取L1数据,L1代码,L2和L3缓存大小的程序。
我试图在英特尔文档中找到一些东西。在互联网上,但我失败了。
主要问题是:对于AMD处理器,只需将EAX寄存器设置为80000005h& 80000006h值并从ECX和EDX寄存器获取所需数据,但在Intel的情况下,我只能获取L2的此信息。
我应该怎么做才能获得L1&英特尔处理器的L3缓存大小?
答案 0 :(得分:3)
Marat Dukhan基本上给了你正确的答案。对于较新的英特尔处理器,意味着在过去的5 - 6年中制作的处理器,最好的解决方案是枚举cpuid leaf 4,这意味着你多次调用cpuid,首先是EAX = 4和ECX = 0,然后是EAX = 4和ECX = 1等等。这将不仅返回缓存大小和类型的信息,还会告诉您这些缓存如何连接到CPU内核和超线程/ SMT单元。算法和示例代码在https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/给出,更具体地在标题为" Cache Topology Enumeration"的部分中给出。
答案 1 :(得分:1)
对于Intel CPU:
对于较新的CPU,您应该使用“ CPUID,eax = 0x00000004”(在ECX中使用不同的值)
对于较旧的CPU(不支持第一个选项),应使用“ CPUID,eax = 0x00000002”。这涉及到有一个表来查找值的含义。在某些情况下,相同的值对于不同的CPU意味着不同的情况,并且您需要其他信息(例如CPU系列/型号/步进)。
对于VIA CPU;使用与英特尔相同的方法(对于涉及“家庭/模型/步进”的任何事物使用不同的表)。
对于AMD CPU:
对于较新的CPU,您应该使用“ CPUID,eax = 0x8000001D”(在ECX中使用不同的值)
对于较旧的CPU(不支持第一个选项),应使用“ CPUID,eax = 0x80000006”(仅适用于L2和L3),以及“ CPUID,eax = 0x80000005”(仅适用于L1)
对于所有其他情况(非常旧的Intel / VIA / AMD CPU,其他制造商的CPU):
使用CPU“供应商/家庭/型号/步进”(来自“ CPUID,eax = 0x0000001”)和一个表(或每个供应商1个表),以便您可以在表/中搜索合适的CPU /并以这种方式获取信息。
如果不支持CPUID
,可以通过多种方法来缩小可能性,并以合理的精度确定CPU的状态。但大多数情况下,您应该放弃。
此外;对于所有CPU,应在勘误表中进行遍历,以查看CPUID是否提供了错误的信息;并实施变通办法以纠正错误的信息。
请注意(取决于您所支持的CPU范围和您想要的代码性能),仅要提取有关缓存的可靠信息就可能需要花费几个月的时间。
答案 2 :(得分:0)
您可以使用CPUID指令获取CPU L1,L2和L3缓存大小。 根据《英特尔x86软件开发人员手册》第2卷(指令集参考)。您可以通过EAX等于2或4的CPUID指令来获取CPU缓存信息。EAX = 2是较旧的版本,似乎新的CPU不使用它。因此,我将介绍EAX = 4的情况。
其输出格式为:
因此您可以使用以下公式计算缓存大小:
缓存大小=(方式+ 1)*(分区+ 1)*(Line_Size + 1)*(集合+ 1)或
缓存大小=(EBX [31:22] +1)*(EBX [21:12] +1)*(EBX [11:0] +1)*(ECX +1)
例如,我在ubuntu系统中执行“ cpuid -li”指令,并获得以下输出:
deterministic cache parameters (4):
--- cache 0 ---
cache type = data cache (1)
cache level = 0x1 (1)
self-initializing cache level = true
fully associative cache = false
extra threads sharing this cache = 0x1 (1)
extra processor cores on this die = 0x7 (7)
system coherency line size = 0x3f (63)
physical line partitions = 0x0 (0)
ways of associativity = 0x7 (7)
ways of associativity = 0x0 (0)
WBINVD/INVD behavior on lower caches = false
inclusive to lower caches = false
complex cache indexing = false
number of sets - 1 (s) = 63
--- cache 1 ---
cache type = instruction cache (2)
cache level = 0x1 (1)
self-initializing cache level = true
fully associative cache = false
extra threads sharing this cache = 0x1 (1)
extra processor cores on this die = 0x7 (7)
system coherency line size = 0x3f (63)
physical line partitions = 0x0 (0)
ways of associativity = 0x7 (7)
ways of associativity = 0x0 (0)
WBINVD/INVD behavior on lower caches = false
inclusive to lower caches = false
complex cache indexing = false
number of sets - 1 (s) = 63
--- cache 2 ---
cache type = unified cache (3)
cache level = 0x2 (2)
self-initializing cache level = true
fully associative cache = false
extra threads sharing this cache = 0x1 (1)
**extra processor cores on this die = 0x7 (7)
system coherency line size = 0x3f (63)
physical line partitions = 0x0 (0)**
ways of associativity = 0x3 (3)
ways of associativity = 0x0 (0)
WBINVD/INVD behavior on lower caches = false
inclusive to lower caches = false
complex cache indexing = false
number of sets - 1 (s) = 1023
--- cache 3 ---
cache type = unified cache (3)
cache level = 0x3 (3)
self-initializing cache level = true
fully associative cache = false
extra threads sharing this cache = 0xf (15)
extra processor cores on this die = 0x7 (7)
system coherency line size = 0x3f (63)
physical line partitions = 0x0 (0)
ways of associativity = 0xb (11)
ways of associativity = 0x6 (6)
WBINVD/INVD behavior on lower caches = false
inclusive to lower caches = true
complex cache indexing = true
number of sets - 1 (s) = 12287
L1数据缓存大小为:(7 + 1)(0 + 1)(63 + 1)*(63 + 1)= 32K
L3缓存大小为:(11 + 1)(0 + 1)(63 + 1)*(12287 + 1)= 9M