记录了Intel x86处理器的L1内存缓存在哪里?

时间:2009-04-04 00:08:22

标签: performance intel cpu-architecture cpu-cache

我正在尝试分析和优化算法,我想了解缓存对各种处理器的具体影响。对于最近的Intel x86处理器(例如Q9300),很难找到有关缓存结构的详细信息。特别是,发布处理器规范的大多数网站(包括Intel.com)都不包含对L1缓存的任何引用。这是因为L1缓存不存在还是由于某种原因被认为不重要?是否有关于消除L1缓存的文章或讨论?

[编辑] 在运行各种测试和诊断程序(主要是在下面的答案中讨论的那些)后,我得出结论,我的Q9300似乎有一个32K L1数据缓存。我仍然没有找到一个明确的解释,为什么这些信息很难得到。我目前的工作理论是,L1缓存的细节现在被英特尔视为商业机密。

7 个答案:

答案 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个周期。

另请参阅标记wiki,以获取更多性能和微架构数据的链接。

答案 1 :(得分:26)

本英特尔手册:英特尔®64和IA-32架构优化参考手册对缓存注意事项进行了大量讨论。

enter image description here

第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应该消除任何疑问。用他的话来说,“记忆就是新盘!”。

Haswell’s URS (Unified Reservation Station)

更新II:SkyLake显着改善了缓存性能规范。

SkyLake Cache Specifications

答案 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查询Setscpuideax0x04

提供头文件声明

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);
}