我正在尝试分析和优化算法,我想了解缓存对各种处理器的具体影响。对于最近的Intel x86处理器(例如Q9300),很难找到有关缓存结构的详细信息。特别是,发布处理器规范的大多数网站(包括Intel.com)都不包含对L1缓存的任何引用。这是因为L1缓存不存在还是由于某种原因被认为不重要?是否有关于消除L1缓存的文章或讨论?
[编辑] 在运行各种测试和诊断程序(主要是在下面的答案中讨论的那些)后,我得出结论,我的Q9300似乎有一个32K L1数据缓存。我仍然没有找到一个明确的解释,为什么这些信息很难得到。我目前的工作理论是,L1缓存的细节现在被英特尔视为商业机密。
答案 0 :(得分:61)
几乎不可能找到英特尔缓存的规格。当我去年在高速缓存上教课时,我问过英特尔内部的朋友(在编译器组中)和他们找不到规格。
但等等!!! Jed,祝福他的灵魂,告诉我们在Linux系统上,你可以从内核中挤出大量信息:
grep . /sys/devices/system/cpu/cpu0/cache/index*/*
这将为您提供关联性,设置大小和一堆其他信息(但不是延迟)。 例如,我了解到虽然AMD宣传他们的128K L1缓存,但我的AMD机器有一个64K的分割I和D缓存。
由于Jed,现在两个建议已经过时了:
AMD发布了有关其缓存的更多信息,因此您至少可以获得有关现代缓存的一些信息。例如,去年的AMD L1缓存每个周期(峰值)发出两个字。
开源工具valgrind
内部有各种缓存模型,对于分析和理解缓存行为非常有用。它附带了一个非常好的可视化工具kcachegrind
,它是KDE SDK的一部分。
例如:在2008年第三季度,AMD K8 / K10 CPU使用64字节高速缓存行,每个L1I / L1D分离高速缓存为64kB。 L1D是双向关联的,与L2独占,延迟为3个周期。 L2缓存是16路关联的,延迟大约是12个周期。
AMD Bulldozer-family CPUs使用一个分裂L1,每个群集有一个16kiB 4路关联L1D(每个核心2个)。
Intel CPU长期保持L1相同(从Pentium M到Haswell再到Skylake,之后可能是很多代):每个I和D缓存分割32kB,L1D为8路关联。 64字节高速缓存行,与DDR DRAM的突发传输大小相匹配。负载使用延迟约为4个周期。
另请参阅x86标记wiki,以获取更多性能和微架构数据的链接。
答案 1 :(得分:26)
本英特尔手册:英特尔®64和IA-32架构优化参考手册对缓存注意事项进行了大量讨论。
第46页,第2.2.5.1节Intel® 64 and IA-32 Architectures Optimization Reference Manual
即便是MicroSlop也意识到需要更多工具来监控缓存使用情况和性能,并且有一个GetLogicalProcessorInformation() function示例(...在创建过程中创建可笑的长函数时开辟新的道路)我认为我会编码。
更新I:Hazwell从Inside the Tock; Haswell's Architecture
增加了2倍的缓存加载性能如果有任何疑问,最好尽可能地使用缓存,那么以前由Azul提供的Cliff Click this presentation应该消除任何疑问。用他的话来说,“记忆就是新盘!”。
更新II:SkyLake显着改善了缓存性能规范。
答案 2 :(得分:8)
您正在查看消费者规范,而不是开发人员规范。 Here is the documentation you want.缓存大小因处理器系列子模型而异,因此它们通常不在IA-32开发手册中,但您可以轻松地在NewEgg上查找它们。
编辑更具体地说:第3A卷(系统编程指南)的第10章,优化参考手册的第7章,以及TLB页面缓存手册中的某些内容,尽管我会假设一个比你关心的更远离L1。
答案 3 :(得分:8)
我做了更多调查。苏黎世联邦理工学院有一个小组建立了一个memory-performance evaluation tool,它可能能够获得有关L1和L2缓存的至少(也可能是相关性)大小的信息。该程序通过实验尝试不同的读取模式并测量产生的吞吐量来工作。 popular textbook by Bryant and O'Hallaron使用了简化版本。
答案 4 :(得分:2)
这些平台上存在L1缓存。在存储器和前端总线速度超过CPU的速度之前,这几乎肯定会一直存在,这很可能还有很长的路要走。
在Windows上,您可以使用GetLogicalProcessorInformation获取某种级别的缓存信息(大小,行大小,关联性等).Win7上的Ex版本将提供更多数据,例如哪些核心共享哪个缓存。 CpuZ也提供此信息。
答案 5 :(得分:2)
Locality of Reference对某些算法的性能有重大影响; L1,L2(以及更新的CPU L3)缓存的大小和速度显然在这方面发挥了重要作用。矩阵乘法就是这样一种算法。
答案 6 :(得分:1)
英特尔手册卷。 2指定以下公式来计算缓存大小:
此缓存大小(以字节为单位)
=(方式+ 1)*(分区+ 1)*(Line_Size + 1)*(集合+ 1)
=(EBX [31:22] +1)*(EBX [21:12] +1)*(EBX [11:0] +1)*(ECX +1)
在Ways
设置为Partitions
的情况下,使用Line_Size
查询Sets
,cpuid
,eax
和0x04
。
提供头文件声明
x86_cache_size.h
:
unsigned int get_cache_line_size(unsigned int cache_level);
实现如下:
;1st argument - the cache level
get_cache_line_size:
push rbx
;set line number argument to be used with CPUID instruction
mov ecx, edi
;set cpuid initial value
mov eax, 0x04
cpuid
;cache line size
mov eax, ebx
and eax, 0x7ff
inc eax
;partitions
shr ebx, 12
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;ways of associativity
shr ebx, 10
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;number of sets
inc ecx
mul ecx
pop rbx
ret
我的机器上的工作方式如下:
#include "x86_cache_size.h"
int main(void){
unsigned int L1_cache_size = get_cache_line_size(1);
unsigned int L2_cache_size = get_cache_line_size(2);
unsigned int L3_cache_size = get_cache_line_size(3);
//L1 size = 32768, L2 size = 262144, L3 size = 8388608
printf("L1 size = %u, L2 size = %u, L3 size = %u\n", L1_cache_size, L2_cache_size, L3_cache_size);
}