深度学习arm cache系列--一篇就够了

快速链接:

  • 【精选】ARMv8/ARMv9架构入门到精通-[目录] 👈👈👈

1. cache的基本概念介绍

1.1、为什么要用cache?

ARM 架构刚开始开发时,处理器的时钟速度和内存的访问速度大致相似。今天的处理器内核要复杂得多,并且时钟频率可以快几个数量级。然而,外部总线和存储设备的频率并没有达到同样的程度。可以实现可以与内核以相同速度运行的小片上 SRAM块,但与标准 DRAM 块相比,这种 RAM 非常昂贵,标准 DRAM 块的容量可能高出数千倍。在许多基于 ARM 处理器的系统中,访问外部存储器需要数十甚至数百个内核周期。

高速缓存是位于核心和主内存之间的小而快速的内存块。它在主内存中保存项目的副本。对高速缓冲存储器的访问比对主存储器的访问快得多。每当内核读取或写入特定地址时,它首先会在缓存中查找。如果它在高速缓存中找到地址,它就使用高速缓存中的数据,而不是执行对主存储器的访问。通过减少缓慢的外部存储器访问时间的影响,这显着提高了系统的潜在性能。通过避免驱动外部信号的需要,它还降低了系统的功耗
在这里插入图片描述

1.2、为什么要学习cache呢?

cache和我们软件工程师有啥关系?其实在很多时候,都没有太大的关系,在很多时候也无需去理解cache的原理。但事实就是事实,不管你理解还是不理解,你都是一直在用的。做为一名底层的软件开发者,在有些时候,你不得不去主动刷新cache,即软件中维护内存一致性 。
那么一般什么时候需要主动刷cache呢(软件中维护内存一致性) ? 基本就是当有不同的Master来访问相同的内存的时候。如下便是几个小示例。

1.2.1、软件中维护内存一致性 – invalid cache

在这里插入图片描述

1.2.2、软件中维护内存一致性 – flush cache

在这里插入图片描述

1.3、怎么去刷cache呢?

ARM提供了操作cache的指令, 软件维护操作cache的指令有三类:

  • Invalidation:其实就是修改valid bit,让cache无效,主要用于读
  • Cleaning: 其实就是我们所说的flush cache,这里会将cache数据回写到内存,并清楚dirty标志
  • Zero:将cache中的数据清0, 这里其实是我们所说的clean cache.

什么时候需要软件维护cache
(1)、当有其它的Master改变的external memory,如DMA操作
(2)、MMU的enable或disable的整个区间的内存访问,如REE enable了mmu,TEE disable了mmu.

针对第(2)点,cache怎么和mmu扯上关系了呢?那是因为:
mmu的开启和关闭,影响了内存的permissions, cache policies

1.3.1、cache一致性指令介绍

因为本节为第一篇,也就是基本的概念介绍。我们很多深入的原理还不明白。所以就不对以下指令做深入的解读。你只需理解有这么多指令可用于“软件维护cache的一致性”就好。后续当深入理解了cache的各种策略原理后,再回过头来看这些指令,相信会有较大的收获。

在这里插入图片描述
以下是对维护cache的一致性指令做出的一个总结
在这里插入图片描述

1.3.2、cache一致性指令的使用示例

在这里插入图片描述

1.3.3、 操作系统中软件维护cache一致性的API

在操作系统中,我们只需要调用相关的API即可,也无需牢记以上的维护cache一致性的命令。

比如在Linux Kernel 操作Cache的API如下所示:

linux/arch/arm64/mm/cache.S
linux/arch/arm64/include/asm/cacheflush.hvoid __flush_icache_range(unsigned long start, unsigned long end);
int  invalidate_icache_range(unsigned long start, unsigned long end);
void __flush_dcache_area(void *addr, size_t len);
void __inval_dcache_area(void *addr, size_t len);
void __clean_dcache_area_poc(void *addr, size_t len);
void __clean_dcache_area_pop(void *addr, size_t len);
void __clean_dcache_area_pou(void *addr, size_t len);
long __flush_cache_user_range(unsigned long start, unsigned long end);
void sync_icache_aliases(void *kaddr, unsigned long len);
void flush_icache_range(unsigned long start, unsigned long end)
void __flush_icache_all(void)
1.4、总结

小小总结一下,当有其它硬件(如DMA)和CPU访问同一块内存时,那么这个时候的操作需要小心,一般也就是记得调用invalid cache和flush cache相关的函数即可

2. cache的基本概念原理扫盲

2.1、cache是多级相连的

cache是多级的,在一个系统中你可能会看到L1、L2、L3, 当然越靠近core就越小,也是越昂贵。
一般来说,对于bit.LITTLE架构中,在L1是core中,L1又分为L1 data cache和 L1 Instruction cache, L2 cache在cluster中,L3则在BUS总线上。
在这里插入图片描述

2.2、cache一般是和MMU结合在一起使用的

很多时候cache都是和MMU一起使用的(即同时开启或同时关闭),因为MMU页表的entry的属性中控制着内存权限和cache缓存策略等
在这里插入图片描述
在ARM架构中,L1 cache都是VIPT的,也就是当有一个虚拟地址送进来,MMU在开始进行地址翻译的时候,Virtual Index就可以去L1 cache中查询了,MMU查询和L1 cache的index查询是同时进行的。如果L1 Miss了,则再去查询L2,L2还找不到则再去查询L3。 注意在arm架构中,仅仅L1是VIPT,L2和L3都是PIPT。
在这里插入图片描述

2.3、bit-LITTLE架构 和 DynamIQ架构 的cache是有区别的
2.3.1 bit-LITTLE架构的cache

以下是一张比较早期的经典的bit-LITTLE的架构图
在这里插入图片描述
bit-LITTLE的架构中,L1是在core中的,是core私有的;L2是在cluster中的,对cluster中的core是共享的;L3则对所有cluster共享。bit-LITTLE的架构的一个cache层级关系图如下所示:
在这里插入图片描述

2.3.2 DynamIQ架构架构的cache

随着时代的发展科技的进步,除了了DynamIQ架构后,整个系统的system memory架构也在悄然无息的发生了变化。刚开始的架构如下所示:L1/L2在core中,L3在DSU中,DSU对外是ACE接口,结合CCI 来维护多cluster之间的缓存一致性。
在这里插入图片描述
但是在后来,随着CHI的越来越成熟,又变成了:L1/L2在core中,L3在DSU中,DSU对外是CHI接口,结合CMN来维护多cluster之间的缓存一致性。
在这里插入图片描述
但是不管怎么说,在dynamIQ的架构中,L1和L2都在core中的,都是core私有的;L3则是在cluster中的,对cluster中的core是共享的;如有L3或system cache,则是所有cluster共享。dynamIQ的架构的一个cache层级关系图如下所示:
在这里插入图片描述

2.4、L1/L2/L3 cache的大小

可以参考ARM文档,其实每一个core的cache大小都是固定的或可配置的。
在这里插入图片描述

2.5、cache的组织形式(index, way, set)

cache的组织形式有:

  • 全相连
  • 直接相连
  • 多路组相连(如4路组相连)

在这里插入图片描述
在一个core中一个架构中一个SOC中,所有cache的组织形式并不是都一样的。即使L1 D-cache和L1 I-cache的组织形式,也都可能不是一样的的。 具体的组织形式是怎样的,需要查询你的core trm手册。

因为有了多路组相连这个cache,所以也就有了这些术语概念:

  • index : 用白话理解,其实就是在一块cache中,一行一行的编号(事实是没有编号/地址的)
  • Set :用index查询到的cache line可能是多个,这些index值一样的cacheline称之为一个set
  • way:用白话来说,将cache分成了多个块(多路),每一块是一个way
  • cache TAG :查询到了一行cache后,cachelne由 TAG + DATA组成
  • cache Data :查询到了一行cache后,cachelne由 TAG + DATA组成
  • cache Line 和 entry 是一个概念

在这里插入图片描述

2.6、cache的种类(VIVT,PIPT,VIPT)

cache一般是有如下种类;

  • PIPT
  • VIVT
  • VIPT

在一个core中一个架构中一个SOC中,你所使用的cache是哪种类型的,都是固定的,是软件改不了的。在ARM架构中,一般L1 cache都是VIPT的,其余的都是PIPT的。
VIPT和PIPT的原理,基本也都是一样的,只是硬件查询时稍微有一丁点的区别,在后续讲cache查询时会再次介绍。

那么,你还学什么VIVT?你为什么还要去理解VIVT的原理?你为什么还要去分析cache同名、重名的问题? 这样的问题,在armv7/armv8/armv9架构中都是不存在的

2.7、cache的分配策略(alocation,write-through, write-back)
  • 读分配(read allocation)
    当CPU读数据时,发生cache缺失,这种情况下都会分配一个cache line缓存从主存读取的数据。默认情况下,cache都支持读分配。

  • 读分配(read allocation)写分配(write allocation)
    当CPU写数据发生cache缺失时,才会考虑写分配策略。当我们不支持写分配的情况下,写指令只会更新主存数据,然后就结束了。当支持写分配的时候,我们首先从主存中加载数据到cache line中(相当于先做个读分配动作),然后会更新cache line中的数据。

  • 写直通(write through)
    当CPU执行store指令并在cache命中时,我们更新cache中的数据并且更新主存中的数据。cache和主存的数据始终保持一致。

  • 读分配(read allocation)写回(write back)
    当CPU执行store指令并在cache命中时,我们只更新cache中的数据。并且每个cache line中会有一个bit位记录数据是否被修改过,称之为dirty bit(翻翻前面的图片,cache line旁边有一个D就是dirty bit)。我们会将dirty bit置位。主存中的数据只会在cache line被替换或者显示的clean操作时更新。因此,主存中的数据可能是未修改的数据,而修改的数据躺在cache中。cache和主存的数据可能不一致
    在这里插入图片描述

2.8、架构中定义的cache的范围(inner, outer)

对于cacheable属性,inner和outer描述的是cache的定义或分类。比如把L1/L1看做是inner,把L3看做是outer

通常,内部集成的cache属于inner cache,外部总线AMBA上的cache属于outer cache。例如:

  • 对于big.LITTLE架构(A53为例)中,L1/L2属于inner cache,如果SOC上挂了L3的话,则其属于outer cache
  • 对于DynamIQ架构(A76为例)中,L1/L2/L3属于inner cache,如果SOC上挂了System cache(或其它名称)的话,则其属于outer cache

然后我们可以对每类cache进行单独是属性配置,例如:

  • 配置 inner Non-cacheable 、配置 inner Write-Through Cacheable 、配置 inner Write-back Cacheable
  • 配置 outer Non-cacheable 、配置 outer Write-Through Cacheable 、配置 outer Write-back Cacheable
    在这里插入图片描述

对于shareable属性,inner和outer描述的是cache的范围。比如inner是指L1/L2范围内的cache,outer是指L1/L2/L3范围内的cache
在这里插入图片描述

2.9、架构中内存的类型

在arm架构中,将物理内存分成了device和normal两种类型
在这里插入图片描述

而是每种的内存下(device和normal)又分出了多种属性。ARM提供一个MAIR寄存器, 将一个64位的寄存器分成8个attr属性域,每个attr属性域有8个比特,可配置成不同的内存属性。
也就是说,在一个arm core,最多支持8中物理内存类型。
在这里插入图片描述

而我们在MMU使用的页表的entry中的属性位中,BIT[4:2]占3个比特,表示index,其实就是指向MAIR寄存器中的attr。
在这里插入图片描述
也就说说,页表的每一个entry中,都指向MAIR寄存器中的一个属性域。也就是页表的每一个entry都配置了一种内存类型。

3. cache的查询原理

3.1. cache的查询原理

高速缓存控制器(cache controller )是负责管理高速缓存内存的硬件块,其方式对程序来说在很大程度上是不可见的。它自动将代码或数据从主存写入缓存。它从core接收读取和写入内存请求,并对高速缓存或外部存储器执行必要的操作。

当它收到来自core的请求时,它必须检查是否能在缓存中找到所请求的地址。这称为缓存查找(cache look-up)。它通过将请求的地址位的subset(index)与与缓存中的physical TAG 进行比较来做到这一点。如果存在匹配,称为命中(hit),并且该行被标记为有效,则使用高速缓存进行读取或写入。

当core从特定地址请求指令或数据,但与缓存标签不匹配或标签无效时,会导致缓存未命中,请求必须传递到内存层次结构的下一层,即 L2缓存或外部存储器。它还可能导致缓存行填充。缓存行填充会导致将一块主内存的内容复制到缓存中。同时,请求的数据或指令被流式传输到core。这个过程软件开发人员不能直接看到。在使用数据之前,core不需要等待 linefill 完成。高速缓存控制器通常首先访问高速缓存行内的关键字。例如,如果您执行的加载指令在缓存中未命中并触发缓存行填充,则内核首先检索缓存行中包含所请求数据的那部分。这些关键数据被提供给core流水线,而缓存硬件和外部总线接口随后在后台读取缓存线的其余部分。
在这里插入图片描述
总结一下就是:先使用index去查询cache,然后再比较TAG,比较TAG之后再检查valid标志位。
但是这里要注意:TAG包含了不仅仅是物理地址,还有很多其它的东西,如NS比特位等,这些都是在比较TAG的时候完成。

3.2. cache的查询示例

在这里插入图片描述
假设一个4路相连的cache(如cortex-A710),大小64KB, cache line = 64bytes,那么 1 way = 16KB,indexs = 16KB / 64bytes = 256 (注: 0x4000 = 16KB、0x40 = 64 bytes)

0x4000 – index 0
0x
4040 – index 1
0x4080 – index 2

0x
7fc0 – index 255

0x8000 – index 0
0x
8040 – index 1
0x8080 – index 2

0x
bfc0 – index 255

细心的同学可以发现,这里就有了一个很大的问题,你用于cache look-up的index是vaddr[15:6], 如果granue size是4KB,那么vaddr[11:0] = paddrr[11:0] , 但是vaddr[15:12]比特并不等于paddrr[15:12] ,那么你这样的index查询的cache有效吗?会不会发生同名、歧义 ?

其实大可不必担心,因为对于每个core,L1是VIPT的,其实它们的L1 Cache TAG中,已经规定了physical address[39:12],正好是到BIT12。所以只要TAG比较之后,就不会出现同名和歧义。
在这里插入图片描述

4. 多核多cluster多系统之间缓存一致性概述

4.1. 质疑

网上的好多篇博文,一提Cache的多核一致性就必然提到MESI、MOESI ,然后就开始讲MESI、MOESI维护性原理?试问一下,您是真的不理解MES吗?您真的需要学习MESI?你不理解的是架构对吧,而不是学什么鬼协议!

既然您要学了MESI,那么这里也提出几个问题:
(1)、ARM架构中真的使用MESI了吗? 或者是哪一级使用了,哪一级没有使用?
(2)、MESI是一个协议? 是谁来维护的?总得有个硬件实现这个协议吧,是在ARM Core中? CCI-400中?SCU中?DSU中?
(3)、MESI的四种状态,分别记录在哪里的?

4.2. 怎样去维护多核多系统缓存的一致性

有三种机制可以保持一致性:

  • 禁用缓存是最简单的机制,但可能会显着降低 CPU 性能。为了获得最高性能,处理器通过管道以高频率运行,并从提供极低延迟的缓存中运行。缓存多次访问的数据可显着提高性能并降低 DRAM 访问和功耗。将数据标记为“非缓存”可能会影响性能和功耗。
  • 软件管理的一致性是数据共享问题的传统解决方案。在这里,软件(通常是设备驱动程序)必须清除或刷新缓存中的脏数据,并使旧数据无效,以便与系统中的其他处理器或主设备共享。这需要处理器周期、总线带宽和功率。
  • 硬件管理的一致性提供了一种简化软件的替代方案。使用此解决方案,任何标记为“共享”的缓存数据将始终自动更新。该共享域中的所有处理器和总线主控器看到的值完全相同。

燃鹅,我们在ARM架构中,默认使用的却是第三种 硬件管理的一致性, 意思就是:做为一名软件工程师,我们啥也不用管了,有人帮我们干活,虽然如此,但我们还是希望理解下硬件原理。

再讲原理之前,我们先补充一个场景:
假设在某一操作系统中运行了一个线程,该线程不停着操作0x4000_0000地址处内存(所以我们当然期望,它总是命中着),由于系统调度,这一次该线程可能跑在cpu0上,下一次也许就跑在cpu1上了,再下一次也许就是cpu4上了(其实这种行为也叫做CPU migration)

或者举个这样的场景也行:
在Linux Kernel系统中,定义了一个全局性的变量,然后多个内核线程(多个CPU)都会访问该变量.

在以上的场景中,都存在一块内存(如0x4000_0000地址处内存)被不同的ARM CORE来访问,这样就会出现了该数据在main-memory、SCU-0的L2 cache、SCU-1的L2 cache、8个Core的L1 cache不一致的情况。

既然出现了数据在内存和不同的cache中的不一致的情况,那么就需要解决这个问题(也叫维护一致性),那么怎么维护的呢,上面也说了“使用 硬件管理的一致性”,下面就以直接写答案的方式,告诉你硬件是怎样维护一致性的。

4.3. bit.LITTLE架构 和 DynamIQ架构 的系统中的缓存一致性

我们先看一张的图(bit.LITTLE架构的)吧

  • core1、core1的cache的一致性,是由SCU-0来维护的(至于这里是不是遵守了MESI协议,答案:YES)
  • cluster0、cluster1的cache的一致性,是由于CCI-400来维护的(至于这里是不是遵守了MESI协议,答案:NO)
    在这里插入图片描述
    再看一张比较的图(DynamIQ架构的)吧
  • core0的cache(含L1/L2)、core1的cache(含L1/L2)的一致性 由DSU-0来维护(至于这里是不是遵守了MESI协议,答案: YES)
  • cluster0的 L3 cache、cluster1的 L3 cache、Mali的L2 cache的一致性是由于CCI-550来维护的(至于这里是不是遵守了MESI协议,NO)
    在这里插入图片描述
4.4. MESI、MOESI 的介绍

注意着仅仅是一个协议 ,它既不是软件也不是硬件,算上一个标准吧。既然只是一个协议(标准),那总得有硬件来执行维护该协议吧。一般来讲,在core cache之间的一致性是要遵从MESI/MOESI协议的,由SCU(或DSU)硬件来执行维护该协议的。在ARM架构中,也并非所有的缓存都遵从MESI/MOESI协议,仅仅只是在一个cluster中的core cache中,才需要遵从MESI/MOESI协议。而对于不同的core,又遵从着不同的协议,具体请查略你的core TRM手册,上面会说明你的core cache是使用MESI还是MOESI。 接下来我们就来看一下MESI协议部分。

首先是Modified Exclusive Shared Invalid (MESI) 协议中定义了4个状态:

MESI StateDefinition
Modified (M)这行数据有效,数据已被修改,和内存中的数据不一致,数据只存在于该高速缓存中
Exclusive (E)这行数据有效,数据和内存中数据一致,数据只存在于该高速缓存中
Shared (S)这行数据有效,数据和内存中数据一致,多个高速缓存有这行数据的副本
Invalid (I)这行数据无效

其次,在ARM的部分的core中,定义了第五种状态Shared Modified,这种称之为MOESI 协议. 而ARM使用的则是MOESI的变体(啥叫变体,咋变的,变的哪些,文当它没有说)
在这里插入图片描述
然后我们通过数据流图的方式,观看下MESI这四种状态的情况:
在这里插入图片描述
MESI状态之间的切换:
在这里插入图片描述

Events:
RH = Read Hit
RMS = Read miss, shared
RME = Read miss, exclusive
WH = Write hit
WM = Write miss
SHR = Snoop hit on read
SHI = Snoop hit on invalidate
LRU = LRU replacement


Bus Transactions:
Push = Write cache line back to memory
Invalidate = Broadcast invalidate
Read = Read cache line from memory

4.5. 总结
  • 看完以上信息,我们再次总结一下,我们学习cache一致性,我们最大的困惑或瓶颈是啥,是不理解MESI吗?应该还是对架构的理解和认知。学习MESI,不如去学习cache硬件基础、cache TAG、DSU、CCI-550原理吧。
  • 多核之间的缓存一致性,由SCU(DSU)硬件来执行维护,使用MESI协议
  • 多cluster之间的缓存一致性,由 CCI/CMN 来执行维护,没有使用MESI协议

5. 多级cache之间的替换策略

思考:
1、L1 cache的替换策略是什么,L2和L3的呢
2、哪些的替换策略是由硬件决定的(定死的,软件不可更改的),哪些的替换策略是软件可以配置的?
3、在经典的 DynamIQ架构 中,数据是什么时候存在L1 cache,什么时候存进L2 cache,什么时候又存进L3 cache,以及他们的替换策略是怎样的? 比如什么时候数据只在L1? 什么时候数据只在L2? 什么时候数据只在L3? 还有一些组合,比如什么时候数组同时在L1和L3,而L2没有? 这一切的规则是怎样定义的?
说明:
本文讨论经典的DynamIQ的cache架构,忽略 big.LITTLE的cache架构

在这里插入图片描述


5.1、DynamIQ架构中L1 cache的替换策略(以cortex-A710为例)

我们先看一下DynamIQ架构中的cache中新增的几个概念:

  • (1) Strictly inclusive: 所有存在L1 cache中的数据,必然也存在L2 cache中
  • (2) Weakly inclusive: 当miss的时候,数据会被同时缓存到L1和L2,但在之后,L2中的数据可能会被替换
  • (3) Fully exclusive: 当miss的时候,数据只会缓存到L1

其实inclusive/exclusive属性描述的正是是 L1和L2之间的替换策略,这部分是硬件定死的,软件不可更改的。

我们再去查阅 ARMV9 cortex-A710 trm手册,查看该core的cache类型,得知:
在这里插入图片描述

  • L1 I-cache和L2之间是 weakly inclusive的
  • L1 D-cache和L2之间是 strictly inclusive的

也就是说:

  • 当发生D-cache发生miss时,数据缓存到L1 D-cache的时候,也会被缓存到L2 Cache中,当L2 Cache被替换时,L1 D-cache也会跟着被替换
  • 当发生I-cache发生miss时,数据缓存到L1 I-cache的时候,也会被缓存到L2 Cache中,当L2 Cache被替换时,L1 I- cache不会被替换

再次总结 : L1 和 L2之间的cache的替换策略,I-cache和D-cache可以是不同的策略,每一个core都有每一个core的做法,请查阅你使用core的手册。

5.2、core cache的替换策略(以cortex-A710为例)

为了能够将DynamIQ架构和bit.LITTLE架构的cache放在一起介绍,我们将DynamIQ架构中的L1/L2 cache看做成一个单元统称Core cache,bit.LITTLE架构中的L1 Cache也称之为core cache.
DynamIQ架构中DSU中的L3 cache称之为cluster cache,bit.LITTLE架构中SCU中的L2 cache也称之为cluster cache。

5.2.1、L1 data cache 遵从MESI协议

在L1 data cache TAG中,有记录MESI相关比特, 然后将一个core内的cache看做是一个整体,core与core之间的缓存一致性,就由DSU执行MESI协议来维护
在这里插入图片描述

5.2.2、L1 instruction cache 没有遵从MESI协议

因为对于Instruction cache来说,都是只读的,cpu不会改写I-cache中的数据,所以也就不需要硬件维护多核之间缓存的不一致
在这里插入图片描述

5.2.3、MESI协议的介绍

MESI这四种状态:
在这里插入图片描述
MESI状态之间的切换:
在这里插入图片描述

Events:
RH = Read Hit
RMS = Read miss, shared
RME = Read miss, exclusive
WH = Write hit
WM = Write miss
SHR = Snoop hit on read
SHI = Snoop hit on invalidate
LRU = LRU replacement


Bus Transactions:
Push = Write cache line back to memory
Invalidate = Broadcast invalidate
Read = Read cache line from memory

5.3、cluster cache 之间的替换策略

说实话,core cache / cluster cache / 这个名字可能不好,感觉叫private cache 和 share cache也会更好,我也不知道官方一般使用哪个,反正我们能理解其意思即可吧。

那么他们之间的替换策略是怎样的呢?

我们知道MMU的页表中的表项中,管理者每一块内存的属性,其实就是cache属性,也就是缓存策略。
其中就有cacheable和shareable、Inner和Outer的概念。如下是针对 DynamIQ 架构做出的总结,注意哦,仅仅是针对 DynamIQ 架构的cache。

  • 如果将block的内存属性配置成Non-cacheable,那么数据就不会被缓存到cache,那么所有observer看到的内存是一致的,也就说此时也相当于Outer Shareable。
    其实官方文档,也有这一句的描述:
    在B2.7.2章节 “Data accesses to memory locations are coherent for all observers in the system, and correspondingly are treated as being Outer Shareable”

  • 如果将block的内存属性配置成write-through cacheable 或 write-back cacheable,那么数据会被缓存cache中。write-through和write-back是缓存策略。

  • 如果将block的内存属性配置成 non-shareable, 那么core0访问该内存时,数据缓存的到Core0的L1 D-cache / L2 cache (将L1/L2看做一个整体,直接说数据会缓存到core0的private cache更好),不会缓存到其它cache中。

  • 如果将block的内存属性配置成 inner-shareable, 那么core0访问该内存时,数据只会缓存到core 0的L1 D-cache / L2 cache和 DSU L3 cache,不会缓存到System Cache中(当然如果有system cache的话 ) , (注意这里MESI协议其作用了)此时core0的cache TAG中的MESI状态是E, 接着如果这个时候core1也去读该数据,那么数据也会被缓存core1的L1 D-cache / L2 cache 和DSU0的L3 cache(白字黑字,绝不瞎说,请参见文末的[1] DSU TRM片段), 此时core0和core1的MESI状态都是S

  • 如果将block的内存属性配置成 outer-shareable, 那么core0访问该内存时,数据会缓存到core 0的L1 D-cache / L2 cache 、cluster0的DSU L3 cache 、 System Cache中, core0的MESI状态为E。如果core1再去读的话,则也会缓存到core1的L1 D-cache / L2 cache,此时core0和core1的MESI都是S。这个时候,如果core7也去读的话,数据还会被缓存到cluster1的DSU L3 cache. 至于DSU0和DSU1之间的一致性,非MESI维护,具体怎么维护的请看DSU手册,本文不展开讨论。

Non-cacheablewrite-through
cacheable
write-back
cacheable
non-shareable数据不会缓存到cache
(对于观察则而言,又相当于outer-shareable)
core0访问该内存时,数据缓存的到Core0的L1 D-cache / L2 cache (将L1/L2看做一个整体,直接说数据会缓存到core0的private cache更好),不会缓存到其它cache中同左侧
inner-shareable数据不会缓存到cache
(对于观察则而言,又相当于outer-shareable)
core0访问该内存时,数据只会缓存到core 0的L1 D-cache / L2 cache和 DSU L3 cache,不会缓存到System Cache中(当然如果有system cache的话 ) , (注意这里MESI协议其作用了)此时core0的cache TAG中的MESI状态是E, 接着如果这个时候core1也去读该数据,那么数据也会被缓存core1的L1 D-cache / L2 cache 和DSU0的L3 cache, 此时core0和core1的MESI状态都是S同左侧
outer-shareable数据不会缓存到cache
(对于观察则而言,又相当于outer-shareable)
core0访问该内存时,数据会缓存到core 0的L1 D-cache / L2 cache 、cluster0的DSU L3 cache 、 System Cache中, core0的MESI状态为E。如果core1再去读的话,则也会缓存到core1的L1 D-cache / L2 cache,此时core0和core1的MESI都是S
思考:那么此时core7去读取会怎样?
同左侧
5.4、总结
  • dynamIQ 架构中 L1和L2之间的替换策略,是由core的inclusive/exclusive的硬件特性决定的,软无法更改
  • core cache之间的替换策略,是由SCU(或DSU)执行的MESI协议中定义的,软件也无法更改。
  • cluster cache之间的替换策略,是由于MMU页表中的内存属性定义的(innor/outer/cacheable/shareable),软件可以修改

5.5 参考
  • [1] DSU TRM片段
    在这里插入图片描述

6. A53 cache的架构解读

6.1. A53使用经典的 bit-LITTLE架构

以下是一张比较早期的经典的bit-LITTLE的架构图
在这里插入图片描述
在这里插入图片描述

6.2. A53的cache配置

L1 I-Cache

  • 可配:8KB, 16KB, 32KB, or 64KB
  • cacheline:64bytes
  • 2路组相连
  • 128-bit的读L2 memory的接口

L1 D-Cache

  • 可配:8KB, 16KB, 32KB, or 64KB
  • cacheline:64bytes
  • 4路组相连
  • 256-bit的写L2 memory的接口
  • 128-bit的读L2 memory的接口
  • 64-bit的读L1到datapath
  • 128-bit的写datapath到L1

L2 memory System

  • 集成了SCU( Snoop Control Unit ),做多可以连接4个core
  • SCU内重复拷贝了 L1 Data Cache的TAGs
  • L2 memory system对外的接口,可以是ACE 或 CHI,128-bit宽度

L2 cache

  • 可配置的: 128KB, 256KB, 512KB, 1MB and 2MB.
  • cacheline:64bytes
  • Physically indexed and tagged cache(PIPT)
  • 16路组相连的结构

L1 data cache TAG
A53的L1 Data cache遵从的是MOESI协议,如下所示在L1 data cache的tag中存有MOESI的标记位
在这里插入图片描述
MOESI state
在这里插入图片描述

L1 Instruction cache TAG
L1 instruction cache是只读的,所以也就无需硬件维护的多core之间instruction cache的一致性,所以也就无需组从MOESI协议,以下展示了*L1 Instruction cache的TAG,其中标记为很少,无MESI标记位。
在这里插入图片描述

6.3. cache的层级结构:
  • L1 cache是private的在core中
  • L2 cache是share的在cluster中

在这里插入图片描述

6.4. L2 memory System系统介绍

bit.LITTLE架构中中,在Cluster中,有一个SCU单元,SCU单元主要是执行和维护L1 cache的一致性(MESI协议 或 其变体如MOESI协议)。
在这里插入图片描述
在L2 Memory System的中,除了包含L2 cache,也会包含L1 Duplicate tag RAM(这里指的其实是L1 Data Cache Tags)。
在这里插入图片描述

6.5. 多cluster之间的缓存一致性

cluster和外界的接口,可以是ACE或CHI(目前常用的是ACE,后面的趋势可能是CHI)

在这里插入图片描述

  • 如果使用的是ACE,那么多cluster之间的一致性,依靠CCI + ACE 来维护
  • 如果使用的是CHI,那么多cluster之间的一致性,依靠CMN + CHI来维护

在这里插入图片描述

6.6. CCI的介绍(以CCI-550为例)

CCI-550 包含一个包容性监听过滤器(snoop filter),用于记录存储在ACE 主缓存。

侦听过滤器可以在未命中的情况下响应侦听事务,并侦听适当的主控只有在命中的情况下。Snoop 过滤器条目通过观察来自 ACE 主节点的事务来维护以确定何时必须分配和取消分配条目。

侦听过滤器可以响应多个一致性请求,而无需向所有人广播ACE 接口。例如,如果地址不在任何缓存中,则监听过滤器会以未命中和将请求定向到内存。如果地址在处理器缓存中,则请求被视为命中,并且指向在其缓存中包含该地址的 ACE 端口。

在这里插入图片描述
在这里插入图片描述

6.7. 经典示例框图

在这里插入图片描述


关注"Arm精选"公众号,备注进ARM交流讨论区。

1138106487-65f6cf311889c.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/791686.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基于HTML5的网页设计及应用】——-正则表达式.

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…

ctf_show笔记篇(web入门---SSRF)

ssrf简介 ssrf产生原理: 服务端存在网络请求功能/函数,例如:file_get_contens()这一类类似于curl这种函数传入的参数用户是可控的没有对用户输入做过滤导致的ssrf漏洞 ssrf利用: 用于探测内网服务以及端口探针存活主机以及开放服务探针是否存…

C语言交换二进制位的奇数偶数位

基本思路 我们要先把想要交换的数的二进制位给写出来假如交换13的二进制位,13的二进制位是 0000 0000 0000 0000 0000 0000 0000 1101然后写出偶数位的二进制数(偶数位是1的) 1010 1010 1010 1010 1010 1010 1010 1010然后写出奇数位的二进…

uniapp切换中英文

一、安装 npm install uni-i18n --save 二、创建中英文切换的文件 1.英文en.js文件 2.中文zh_CN.js文件 三、 main.js中引用 // Vue i18n 国际化 import VueI18n from /common/vue-i18n.min.js; Vue.use(VueI18n);// i18n 部分的配置,引入语言包,注意路…

Linux :进程的程序替换

目录 一、什么是程序替换 1.1程序替换的原理 1.2更改为多进程版本 二、各种exe接口 2.2execlp ​编辑 2.2execv 2.3execle、execve、execvpe 一、什么是程序替换 1.1程序替换的原理 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往…

0基础安装配置Linux-ubuntu环境

Vmtools的安装参见 0基础教你安装VM 17PRO-直接就是专业许可证版_vm17许可证-CSDN博客 在vmtools中安装ubuntu 等待安装 这时候发现没有继续按钮,我们关闭这个界面,进入系统中,先更改分辨率 点击这个三角,因为还么有安装成功&am…

【Canavs与艺术】绘制蓝白绶带大卫之星勋章

【图例】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>用Canvas绘制蓝白绶带大卫之星勋章</title><style type&quo…

从 MongoDB 到 PostgreSQL 的大迁移

Infisical&#xff0c;一家做密钥管理的开源商业公司&#xff0c;主要对标的是 HashiCorp Vault Infisical 在过去一年里迅速发展&#xff0c;平台现在每天处理超过 5000 万个密钥&#xff0c;将应用程序配置和私密数据发送给需要的团队、CI/CD 流水线以及服务器 / 应用程序。 …

基于JSP的农产品供销服务系统

背景 互联网的迅猛扩张彻底革新了全球各类组织的运营模式。自20世纪90年代起&#xff0c;中国的政府机关和各类企业便开始探索利用网络系统来处理管理事务。然而&#xff0c;早期的网络覆盖范围有限、用户接受度不高、互联网相关法律法规不完善以及技术开发不够成熟等因素&…

Python如何解决“滑动拼图”验证码(8)

前言 本文是该专栏的第67篇,后面会持续分享python爬虫干货知识,记得关注。 做过爬虫项目的同学,或多或少都会接触到一些需要解决验证码才能正常获取数据的平台。 在本专栏之前的文章中,笔者有详细介绍通过python来解决多种“验证码”(点选验证,图文验证,滑块验证,滑块…

汽车EDI:如何与奔驰建立EDI连接?

梅赛德斯-奔驰是世界闻名的豪华汽车品牌&#xff0c;无论是技术实力还是历史底蕴都在全球汽车主机厂中居于领先位置。奔驰拥有多种车型&#xff0c;多元化的产品布局不仅满足了不同用户画像的需求&#xff0c;也对其供应链体系有着极大的考验。 本文将为大家介绍梅赛德斯-奔驰乘…

在s390x架构机器上构建frps/frpc镜像 —— 筑梦之路

源码&#xff1a;GitHub - fatedier/frp: A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet. # 克隆代码git clone https://github.com/fatedier/frp.git# 切换目录cd frp# 构建frps服务端docker build -t frps:s390x -f …

目标检测——车牌数据集

一、重要性及意义 交通安全与管理&#xff1a;车牌检测和识别技术有助于交通管理部门快速、准确地获取车辆信息&#xff0c;从而更有效地进行交通监控和执法。例如&#xff0c;在违规停车、超速行驶等交通违法行为中&#xff0c;该技术可以帮助交警迅速锁定违规车辆&#xff0…

docker安装jenkins 2024版

docker 指令安装安装 docker run -d --restartalways \ --name jenkins -uroot -p 10340:8080 \ -p 10341:50000 \ -v /home/docker/jenkins:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker jenkins/jenkins:lts访问…

AD方法概述应用

1. 背景 异常(异常值、离群点)一般指的是与标准值或期待值有偏离的样本&#xff0c;即与绝大部分数据“长得不一样”。 2. 异常检测(Anomaly Detection) 2.1 AD的一些特点 1. 异常不一定代表是“坏”的事情&#xff0c;但往往是“有价值”的事情&#xff0c;要对异常的成因感…

贝锐蒲公英企业路由器双机热备,保障异地组网可靠、不中断

对于关键业务&#xff0c;比如&#xff1a;在线支付系统、远程医疗监控系统、重要数据中心等&#xff0c;一旦网络发生故障&#xff0c;可能导致巨大的损失或影响&#xff0c;因此需确保网络拥有极高的可靠性、稳定性和容错能力。 面对此类场景和需求&#xff0c;贝锐蒲公英异…

【数据结构与算法】归并排序(详解:递归与非递归的归并排序 | 赠:冒泡排序和选择排序)

前言 本篇博客会对排序做一个收尾&#xff0c;将最经典的七大排序介绍完毕。 这次的重点正如标题&#xff0c;主要讲的是归并排序&#xff0c;还会带过相对简单很多的冒泡排序和选择排序。在最后还会给这七大排序做出一个时间复杂度和稳定性展示的总结收尾。同时&#xff0c;这…

(4)(4.6) Triducer

文章目录 前言 1 安装triducer 2 故障排除 3 参数说明 前言 Triducer 集速度、温度和深度传感器于一体。埃文在这篇 ardupilot.org 博文底部提供了这些说明(Evan at the bottom of this ardupilot.org blog post)。 1 安装triducer 下面的示例提供了在 Pixhawk 上安装 tri…

C语言中的数组与函数指针:深入解析与应用

文章目录 一、引言二、数组的定义1、数组的定义与初始化2、char*与char[]的区别1. 存储与表示2. 修改内容3. 作为函数参数 三、字符串指针数组1. 定义与概念2. 使用示例3. 内存管理 四、从字符串指针数组到函数指针的过渡1、字符串指针数组的应用场景2、函数指针的基本概念3、如…

【管理咨询宝藏48】AA银行信息科技提升分析报告

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏48】AA银行信息科技提升分析报告 【格式】PPT版本&#xff0c;可编辑 【关键词】战略规划、商业分析、管理咨询 【强烈推荐】这是一套市面上非常…