揭秘CPU Cache工作原理(一)

1. Cache的作用

存储层次结构 篇幅中,详细地说明了计算机设计师引入存储层次结的动机与目的。CPU只能操作内存和寄存器,其每一次的指令操作运算都需要经过从内存获取指令、解码、执行等过程,而内存读取速度远赶不上CPU的速度。在早期时候,内存速度非常缓慢,而价格却十分昂贵,而CPU也并没有特别快。

下图为1980~2000年间,随着CPU时钟速度的加快,CPU和内存在速度上差异日趋显著。

图片

▲ 图片来自EXTREMETECH

下图是1980到2010间,CPU和内存在速度和性能上的差异图。

图片

▲ 图片来自Computer Architecture

随着这差异的扩大,急需引入一种新型的快速内存来弥补两者的差距。而这种新型的高速内存便是“CPU高速缓存(CPU Cache)”。

对于CPU Cache,Wikipedia定义是:

A CPU cache is a hardware cache used by the central processing unit (CPU) of a computer to reduce the average cost (time or energy) to access data from the main memory.

​ 即CPU cache是CPU用来降低从内存访问数据的平均成本(时间或性能)的硬件高速缓存。它位于存储层次结构体系(类似金字塔模型)中自顶向下的第二层,仅次于CPU寄存器。其容量远小于内存,但是读写访问速度接近CPU的时钟频率。

图片

▲ 图片来自Wsfdl.com

根据程序对内存地址访问规律上的局部性(时间局部性和空间局部性)原则,CPU会将最近频繁访问使用或是临近即将使用(CPU获取内存数据以块的形式)的指令或数据存储在cache中,以减少CPU下一次获取该指令的时钟周期。当CPU在访问内存时候,会先去cache中查询所需指令或数据是否已存在,若存在,则不用去访问内存,取而代之的是直接获取并解码执行;若不在高速cache中,则继续向低一层级的内存中去获取该指令,载入高速cache,然后返回给cpu执行。

如今,无论是超低功率、低性能的CPU体系结构,还是高端、高性能的CPU,都使用了cache技术。下图显示了一个拥有二级缓存(L1、L2)的CPU命中率的状态情况,CPU的总命中率随着L2空间大小的增加而迅速上升。L2虽然速率上面稍逊于L1,但是它的空间比L1大许多,而且造价也略低,更大的cache空间提高了CPU的命中率,同时还不会对CPU芯片的尺寸设计、功耗带来其他负面的影响。

图片

▲ 图片来自EXTREMETECH

1.1 Cache相关术语

  • 缓存命中(Cache Hit)

    CPU需要数据时,先去L1搜索,若L1未找到,则接着L2、L3缓存中检索,若找到了所需要的数据,则称为缓存命中。

  • 缓存缺失(Cache Miss)

    若CPU在高速缓存中没有找到所的数据,则CPU必须请求将其从内存或存储设备(操作系统+虚拟存储器+虚拟内存范畴)加载到缓存,这便是缓存未命中。

  • 命中时间(His Rate)

    访问某层存储器层次结构所需要的时间,包括了判断当前的访问是命中还是缺失所需要的时间。

  • 缺失代价(Miss Penalty)

    将相应的数据(内存和cache间的块称为:高速缓存线)从低级存储器复制到高层存储器所需的时间。包括访问块、数据逐层传输、将数据插入发生缺失的层和将信息块传输给请求者的时间。本条来自《计算机组成与设计 · 硬件/软件接口》

1.1.1 Cache的物理位置

前面的存储层次结构图中,描述了Cache位于CPU和内存之间,即物理位置上的第二级。那么这个Cache是在CPU芯片内部还是在主电路板上?其答案是高速Cache(L1、L2、L3或L4)通常集成在CPU芯片上或放置在与CPU有单独总线互连的单独芯片上,而不是主板中。

The L1,L2 and L3 cache is on the processor chip and is not built into the CPU.

但是一些早期的计算机(比如486)则是以外部高速cache的形式,比如该cache是一个单独芯片,通过将其插入到插槽,并嵌入到主板的上面。如今的高速cache都是集成到CPU芯片上。

L1 cache进一步分为两个部分: L1数据缓存和L1指令缓存。后者包含将被CPU核心消耗的指令,而前者用于保存将被写回主存的数据。L1缓存不仅作为指令缓存,而且还保存预解码数据和分支信息。此外,虽然L1数据缓存通常作为输出缓存,L1指令缓存的行为像一个输入缓存。当需要的指令就在获取单元旁边时,这是很有帮助的。

通常情况下,当CPU Cache大小增加时,其缓存命中时间也随着增加。这在大型游戏项目中尤其如此。

图片

▲ 图片来自HardWareTimes

1.1.2 CPU Cache和Main Memory异同

– 相同点:

1)都是基于半导体和晶体管制造;

2) 高速缓存(CPU Cache)和主存(Main Memory)都是属于都是易失性存储器,当电源关闭时丢失其内容;

– 差异点:

1)高速缓存只保存主存中最常用的信息或程序代码的副本;

2)高速缓存通常集成在CPU芯片上。主内存(DRAM)放在主板上,并通过内存总线连接到CPU。

3)高速缓存更靠近CPU,因此读写速度比主存更快;

4)主存比高速缓存大很多倍,而且造价更便宜。通常主存为几个G,而高速缓存则为几KB或几MB;

1.2 Cache工作原理

到这里时,我们已经很清楚cache所扮演的角色。但是有两个问题需要确认和解决:

1) 如何去确定CPU需要的数据在cache中?

2) 若数据在cache中,要怎么去寻找搜索?

围绕这两个主要话题,接下来将一步步分析和讲解CPU中cache中的工作方式和原理。(备注:这部分内容将放到 揭秘CPU Cache工作原理(二)中去)。

1.3 查看设备Cache级别和大小

对于类UNIX平台设备,可以直接使用镜像包中系统自带的lscpu命令来查看当前CPU的缓存级别,以及各级缓存大小。当前手里有台服务器 Intel(R) Xeon(R) Gold设备。

[root@node164 ~]# cat /proc/cpuinfo | grep name | cut -f2 -d:| uniq -c
     64Intel(R)Xeon(R) Gold 6130 CPU @ 2.10GHz
复制代码

有64颗逻辑CPU,lscpu命令默认会打印出CPU的详细信息,比如大小端、线程数、时钟周期等,这里使用grep筛选出cache信息,其他的不打印终端。

[root@node164 ~]# lscpu |grep cache
L1d cache:32K
L1i cache:32K
L2 cache:1024K
L3 cache:22528K
复制代码

根据终端信息可知,该CPU体系结构中共有3级缓存,对于L1缓存,大小为64K,其中L1d是L1 Cache for Data, 即数据缓存, L1i是L1 Cache for Instruction, 即指令缓存。L2缓存大小是1024K, L3缓存是22528K。

除了lscpu之外,还可以使用getconf来获取,比如:

[root@node164 ~]# getconf -a|grep CACHE
LEVEL1_ICACHE_SIZE                 32768
LEVEL1_ICACHE_ASSOC                8
LEVEL1_ICACHE_LINESIZE             64
LEVEL1_DCACHE_SIZE                 32768
LEVEL1_DCACHE_ASSOC                8
LEVEL1_DCACHE_LINESIZE             64
LEVEL2_CACHE_SIZE                  1048576
LEVEL2_CACHE_ASSOC                 16
LEVEL2_CACHE_LINESIZE              64
LEVEL3_CACHE_SIZE                  23068672
LEVEL3_CACHE_ASSOC                 11
LEVEL3_CACHE_LINESIZE              64
LEVEL4_CACHE_SIZE                  0
LEVEL4_CACHE_ASSOC                 0
LEVEL4_CACHE_LINESIZE              0
复制代码

其展示的信息以Byte为单位,可以看到和lscpu得到的数据信息是匹配的。

甚至还可以使用dmidecode命令来获取缓存的详细信息:

[root@node164 ~]# dmidecode -t cache
# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 3.0 present.

Handle 0x0074, DMI type 7,19 bytes
Cache Information
        Socket Designation: L1-Cache
        Configuration: Enabled, Not Socketed, Level 1
        Operational Mode: Write Back
        Location: Internal
        Installed Size:1 MB
        Maximum Size:1 MB
        Supported SRAM Types:
                Synchronous
        Installed SRAM Type: Synchronous
        Speed: Unknown
        Error Correction Type: Single-bit ECC
        System Type: Instruction
        Associativity:8-way Set-associative

Handle 0x0075, DMI type 7,19 bytes
Cache Information
        Socket Designation: L2-Cache
        Configuration: Enabled, Not Socketed, Level 2
        Operational Mode: Varies With Memory Address
        Location: Internal
        Installed Size:16 MB
        Maximum Size:16 MB
        Supported SRAM Types:
                Synchronous
        Installed SRAM Type: Synchronous
        Speed: Unknown
        Error Correction Type: Single-bit ECC
        System Type: Unified
        Associativity:16-way Set-associative

· · · · · · more · · · · · ·
复制代码

其中Configuration行即可对应缓存级别的大小信息,比如:

Configuration: Enabled, Not Socketed, Level 1
复制代码

表示L1缓存信息。

除了查看设备CPU体系结构的缓存信息外,还可以使用dmesg来查看内存到高速缓存间数据传输的块大小(高速缓存线,Cache Line)。从下面的终端打印信息可知该Cache Line为64字节。

[root@node164 ~]# dmesg |grep cache
[0.016037] Dentry cache hash table entries:33554432(order:16,268435456 bytes)[0.060792] Inode-cache hash table entries:16777216(order:15,134217728 bytes)[0.078032] Mount-cache hash table entries:524288(order:10,4194304 bytes)[0.078254] Mountpoint-cache hash table entries:524288(order:10,4194304 bytes)[1.481379] PCI: pci_cache_line_size set to 64 bytes
[1.783129] Dquot-cache hash table entries:512(order 0,4096 bytes)[1.992661] xhci_hcd 0000:00:14.0: cache line size of 64 is not supported
[4.079408] sd 7:0:0:0:[sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[4.079435] sd 6:0:0:0:[sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[4.093800] sd 8:0:0:0:[sdc] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[4.114642] sd 9:0:0:0:[sdd] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[4.127546] sd 10:0:0:0:[sde] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[4.143419] sd 11:0:0:0:[sdf] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[4.158524] sd 12:0:0:0:[sdg] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[4.175420] sd 13:0:0:0:[sdh] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
复制代码

另附加一系列与基于NUMA的进程和操作内存统计信息(命中和缺失)的工具,分别是:

[root@node164 CenterController]# numa
numactl   numademo  numastat

[root@node164 CenterController]# numastat
                           node0
numa_hit              1753403168
numa_miss                      0
numa_foreign                   0
interleave_hit             67129
local_node            1753403168
other_node                     0
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享