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

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

有帮助吗?

解决方案

找到有关英特尔缓存的规格几乎是不可能的。去年我在教授缓存课程时,询问了英特尔内部(编译器组)的朋友, 他们 找不到规格。

可是等等!!! 杰德, ,保佑他的灵魂,告诉我们在 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 是 2 路关联且与 L2 互斥,延迟为 3 个周期。L2 缓存为 16 路关联,延迟约为 12 个周期。

AMD Bulldozer 系列 CPU 使用每个集群具有 16kiB 4 路关联 L1D 的拆分 L1(每个核心 2 个)。

Intel CPU 长期以来一直保持 L1 不变(从 Pentium M 到 哈斯韦尔 Skylake,大概是之后的许多代):I 和 D 缓存各分割 32kB,L1D 为 8 路关联。64 字节高速缓存线,与 DDR DRAM 的突发传输大小相匹配。加载使用延迟约为 4 个周期。

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

其他提示

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

enter image description here

第 46 页,第 2.2.5.1 节 英特尔® 64 和 IA-32 架构优化参考手册

甚至 MicroSlop 也意识到需要更多工具来监控缓存使用情况和性能,并且拥有 GetLogicalProcessorInformation() 函数 示例(...同时在此过程中开辟了创建长得可笑的函数名称的新途径)我想我会编写代码。

更新一:Hazwell 将缓存负载性能提高了 2 倍,从 在托克内部;Haswell的架构

如果对充分利用缓存的重要性有任何疑问, 这个演示文稿 由前 Azul 成员 Cliff Click 撰写的文章应该可以消除所有疑虑。用他的话来说,“内存就是新磁盘!”。

Haswell’s URS (Unified Reservation Station)

更新二:SkyLake显着提高了缓存性能规格。

SkyLake Cache Specifications

您正在寻找在消费者规格,不是开发商的规格。 这是你想要的文档。中的高速缓存大小的处理器系列子模型不同,因此它们一般不是在IA-32发展手册,但可以很容易地查找它们对新蛋和这样。

修改更多具体:卷3A(系统编程指南),则优化参考手册的第7章,和潜在的东西在TLB页缓存手册,虽然我假设的第10章一种是再出从L1比你所关心的。

我做更多的一些调查。有一组在苏黎世联邦理工学院是谁建一个内存性能评估工具这也许能够获得有关大小的信息在L1和L2缓存的至少(也许还关联)。该项目工程通过实验尝试不同的读取模式和测量产生的吞吐量。一个简化的版本被用于href="http://csapp.cs.cmu.edu/public/students.html" rel="noreferrer">科比和O'Hallaron 流行教科书的

L1高速缓存在这些平台上存在。直到存储器和前侧总线速度超过CPU的速度,这是一个非常有可能是很长的路要走这将几乎definitly保持真实。

在Windows中,您可以使用 GetLogicalProcessorInformation 得到一些缓存信息(大小,行大小,相关性等)Win7上的防爆版本级别会给更多的数据,如该核心共享哪个缓存。 CPUZ 也给出此信息。

参考的局部性对的一些算法的性能产生重大影响;的大小和L1,L2的速度(和较新的CPU L3)高速缓存中这显然发挥了很大一部分。矩阵乘法是一个这样的算法。

英特尔手册卷。 2指定以下公式来计算高速缓存大小:

  

这个缓存大小(字节)

     

=(途径+ 1)*(分区+ 1)*(Line_Size + 1)*(套+ 1)

     

=(EBX [31:22] + 1)*(EBX [21:12] + 1)*(EBX [11:0] + 1)*(ECX + 1)

WaysPartitionsLine_SizeSets使用的是带有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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top