在准备一个汇编x86项目时,我遇到了一个问题,即编写一个程序以获取L1数据、L1代码、L2和L3缓存大小。
我尝试在英特尔文档和互联网上寻找相关信息,但都没有成功。
主要问题是:对于AMD处理器,只需将EAX寄存器设置为80000005h和80000006h的值,然后从ECX和EDX寄存器中获取所需数据,但对于英特尔处理器,我只能获取L2的信息。
我该怎么做才能获取英特尔处理器的L1和L3缓存大小?
在准备一个汇编x86项目时,我遇到了一个问题,即编写一个程序以获取L1数据、L1代码、L2和L3缓存大小。
我尝试在英特尔文档和互联网上寻找相关信息,但都没有成功。
主要问题是:对于AMD处理器,只需将EAX寄存器设置为80000005h和80000006h的值,然后从ECX和EDX寄存器中获取所需数据,但对于英特尔处理器,我只能获取L2的信息。
我该怎么做才能获取英特尔处理器的L1和L3缓存大小?
getconf LEVEL2_CACHE_SIZE
方面的做法。 glibc源代码可以在以下链接找到:https://superuser.com/questions/55776/how-to-find-the-l2-cache-size-in-linux/1298808#1298808 - Ciro Santilli OurBigBook.com对于Intel CPU:
对于新一代的CPU,您应该使用 "CPUID, eax=0x00000004" (在ECX中使用不同的值)
对于旧一代的CPU(不支持第一个选项),您应该使用 "CPUID, eax=0x00000002"。这需要有一个表格来查找值的含义。在某些情况下,相同的值对于不同的CPU有不同的含义,您需要额外的信息(例如,CPU家族/型号/步进)。
对于VIA CPU:使用与Intel相同的方法(涉及到"family/model/stepping"时使用不同的表格)。
对于AMD CPU:
对于新一代的CPU,您应该使用 "CPUID, eax=0x8000001D" (在ECX中使用不同的值)
对于旧一代的CPU(不支持第一个选项),您应该使用 "CPUID, eax=0x80000006"(仅适用于L2和L3),再加上 "CPUID, eax=0x80000005"(仅适用于L1)。
对于其他所有情况(非常老的Intel / VIA / AMD CPU,其他制造商的CPU):
使用CPU "vendor/family/model/stepping" (从"CPUID,eax=0x0000001")与一个表格(或者也许是每一个制造商一个表格),这样你就可以在你的表格中搜索正确的CPU,并以此获得信息。
如果不支持CPUID
,则有办法尝试缩小可能性并合理准确地确定CPU;但大多数情况下你应该放弃。
此外,对于所有的CPU,你应该查看勘误表,以查看CPUID
是否提供了错误的信息;并实施解决这些错误信息的方法。
请注意,(取决于您支持哪些范围的CPU和您想让您的代码有多棒),仅提取关于高速缓存的可靠信息可能需要几个月的工作。
因此,您可以使用以下公式计算缓存大小:
Cache size = (路数 + 1) * (分区数 + 1) * (行大小 + 1) * (集数 + 1) 或者
Cache size = (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