【ARM】Cache深度解读

Cache的基本概念和使用场景

不同的Master硬件共享数据时---invalid cache


外设和DDR之间没有cache,所以外设直接把数据写入DDR中,但是cpu和DDR之间有cache,cpu会首先访问cache,如果命中直接从cache中拿数据,但是此时的cache并不是最新的数据,cache没有刷新,就拿不到DDR中的数据。此时的解决办法就是在cpu读取数据之前,让cache中的缓存无效,这样就会直接从DDR中读取数据。

不同的Master硬件共享数据时---flush cache

同样还有下面情况,需要刷新cache

不同的缓存策略的系统共享数据时---flush cache

不同的缓存策略的系统共享数据时---invalid cache

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

void __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)

modified的数据地址,在执行invalidate的时候,会先自动执行clean。即

DC IVAC等效于DC CIVAC

cache指令

为什么要用cache?

ARM 架构刚开始开发时,处理器的时钟速度和内存的访问速度大致相似。今天的处理器内核要复杂得多,并且时钟频率可以快几个数量级。然而,外部总线和存储设备的频率并没有达到同样的程度。可以实现可以与内核以相同速度运行的小片上 SRAM 块,但与标准 DRAM 块相比,这种 RAM 非常昂贵,标准DRAM 块的容量可能高出数千倍。在许多基于 ARM 处理器的系统中,访问外部存储器需要数十甚至数百个内核周期。缓存是位于核心和主内存之间的小而快速的内存块。它在主内存中保存项目的副本。对高速缓冲存储器的访问比对主存储器的访问快得多。每当内核读取或写入特定地址时,它首先会在缓存中查找。如果它在高速缓存中找到地址,它就使用高速缓存中的数据,而不是执行对主存储器的访问。通过减少缓慢的外部存储器访问时间的影响,这显着提高了系统的潜在性能。通过避免驱动外部信号的需要,它还降低了系统的功耗。

怎么去刷cache呢? (软件维护cache的一致性)

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

• Invalidation:其实就是修改valid bit,让cache无效。

• Cleaning: 这其实就是我们所说的flush cache,这里就是清除dirty标志,这里会将cache数据回写到内存

• Zero:将cache中的数据清0.

那么一般什么时候需要软件维护cache一致性呢?

(1)、当有其它的Master改变的external memory,如DMA操作

(2)、MMU的enable或disable的整个区间的内存访问,

(3)、当不同缓存策略的系统使用同一块内存通信时,如REE enable了mmu,TEE disable了mmu.

cache一致性指令介绍

总结

按照指令,分为:

• IC : 操作instruction cache,指令cache

• DC : 操作data cache,数据cache

point:刷cache刷到哪个位置

U:一般L1刷到L2

C:从L2往后刷完

IS:刷哪些范围中的cache

按照操作,分为以下三类:

• Invalidation:其实就是修改valid bit,让cache无效。

• Cleaning: 清除cache中的data和TAG,这其实就是我们所说的flush cache,这里会将cache数据回写到内存,并清除dirty标志

• Zero:将cache中的数据清0.

可以以指定只刷L1或L2或L3 cache

Cache的架构

big.LITTLE 和 dynamIQ架构的cache

• 在big.LITTLE 架构中,大核小核在不同的cluster中,做为两个不同的ACE或CHI Master,连接到缓存一致性总线上(CCI或CMN)。大核cluster和小核cluster的缓存一致性,也需要通过一致性总线来解决。

• 到了DynamIQ 架构中,大核和小核都是一个DSU cluster中,一个DSU cluster最多可以支持8个core。如果你的系统是8个core,那么一个DSU就够了,那么系统中也就只有一个ACE或CHI Master,大核和小核之间的一致性,都在DSU cluster内

完成了

dynamIQ架构的cache

Cache是多级相连的

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

cache的种类(VIVT,PIPT,VIPT)

在一个core中一个架构中一个SOC中,你所使用的cache是哪种类型的,都是固定的,是软件改不了的。

在ARM架构中,一般L1 cache都是VIPT的,其余的都是PIPT的。

L1、L2 和 L3 缓存:有什么区别?

三级高速缓存之间的主要区别在于大小、速度以及它们所在的位置。

• L1 缓存的存储容量较低,但通常是计算机中最快的内存,比 RAM 快 100 倍。每个处理器核心都有自

己的 L1 缓存,通常约为 64KB。

• L2 缓存可能比 L1 大几倍,但速度仅为 RAM 的 25 倍左右。与 L1 一样,每个处理器核心都有自己的

L2 缓存。每个通常为 256-512KB,有时高达 1MB。

• L3 缓存具有最大的存储容量,通常为 32MB 或更多,但速度可能仅为系统内存的两倍。L3 缓存通常嵌

入在 CPU 中,但与内核分开。

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

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 是一个概念

cache的分配策略(alocation,write-through, write-back)

读分配(read allocation)

当CPU读数据时,发生cache缺失,这种情况下都会分配一个cache line缓存从主存读取的数据。默认情况下,cache都支持读分配。

写分配(write allocation)

当CPU写数据发生cache缺失时,才会考虑写分配策略。当我们不支持写分配的情况下,写指令只会更新主存数据,然后就结束了。当支持写

分配的时候,我们首先从主存中加载数据到cache line中(相当于先做个读分配动作),然后会更新cache line中的数据。

写直通(write through)

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

写回(write back)

当CPU执行store指令并在cache命中时,我们只更新cache中的数据。并且每个cache line中会有一个bit位记录数据是否被修改过,称之为dirty

bit(翻翻前面的图片,cache line旁边有一个D就是dirty bit)。我们会将dirty bit置位。主存中的数据只会在cache line被替换或者显示的clean

操作时更新。因此,主存中的数据可能是未修改的数据,而修改的数据躺在cache中。cache和主存的数据可能不一致。

cache hit/miss hint的概念

命中(Hit):

当处理器需要访问内存中的数据或指令时,首先会在缓存中查找该数据或指令。

如果缓存中已经包含了所需的数据或指令,则称为"命中"(hit),处理器可以直接从缓存中获取数据,无

需访问主存。

命中通常导致较快的访问速度,因为缓存具有更快的访问时间和更短的延迟。

未命中(Miss):

如果处理器在缓存中未找到所需的数据或指令,则称为"未命中"(miss)。

在发生未命中时,处理器需要从主存中获取所需的数据或指令,然后将其加载到缓存中,以便日后的访问。

未命中通常导致较长的访问延迟,因为需要从相对较慢的主存中加载数据。

命中和未命中的概念可以用来评估缓存系统的性能和效率。高命中率通常表示缓存系统能够有效地提高访

问速度,因为大部分数据都能在缓存中找到。而较高的未命中率可能表明缓存容量不足、替换策略不佳或

者访问模式不合理,需要进行性能优化。

cache的查询原理

cache的层级

cache缓存形式

cache的查询过程

先使用index去查询cache,然后再比较TAG,比较tag的时候还会检查valid标志位

歧义

歧义(ambiguity)也称Homonyms(同名异物)是指一个VA对应不同的PA。例如两个不同的进程,虚拟内

存的地址互相独立,两个不同进程中的相同虚拟内存地址会指向不同的物理内存地址。

歧义主要是因为virtual tag引起的。因为两个不同进程的相同virtual tag可能对应两个不同的physical tag。那么当进程发生切换时,新来的进程B在使用VIVT访问Cache时,很有可能把上一个进程的virtual tag给hit了!!但实际上对应的是不同的physical tag!!这种情况可以使用flush解决:即当发生进程切换时,将Cache flush(clean+invalid)掉,然后再切换到新进程。

同一地址数据(虚拟地址)缓存到了不同的cache中

重名/别名

重名(aliasing),也称Synonyms(同物异名):重名即指多个不同的VA共享同一个PA。

不同地址数据(虚拟地址)缓存到了相同的cache中

解决重名问题:

1、如引入一个新功能:page color

2、物理TAG从BIT12开始

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

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

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

Cluster中的缓存一致性

同一个cluster中多core之间的缓存一致性由DSU(big.LITTLE叫SCU)来维护,遵循MESI协议。

多Master之间的缓存一致性

Master分为以下几类:

• ACE Master : 如 big.LITTLE cluster 或 DSU

cluster

• CHI Master : 如 big.LITTLE cluster 或 DSU

cluster

• ACE-lite Master: 如 GPU cluster

• I/O Device Master : 如 DMA

以下是多Master之间的缓存一致性的结论:

• 首先,CHI/ACE总线都是支持MESI协议数据传输的

• Master与I/O Device Master之间没有一致性,因为I/O Device没有链接到CCI/CMN缓存互联总线上。

• 多个ACE/CHI Master之间的缓存一致性,是否遵循MESI,要具体情况具体分析,简而言之就是:

(1) 如果两个Master都支持带MESI状态位,支持带有MESI信号的读写,那么这两个Master缓存一致性是遵从MESI协议的

(2) 如果有一个Master不支持带MESI状态位,那么这个Master就无法支持带有MESI信号的读写,那么这两个Master缓存一致性是不遵从MESI协议的

(3) Master的MESI状态位,是在该Master的cache的TAG中。

• ACE/CHI Master和ACE-lite Master之间的缓存一致性,是不遵从MESI协议的。这主要是因为ACE/CHI Master无法snoop ACE-lite Master的内存,而ACE-lite Master却可以snoop ACE/CHI Master的内存,总得来说,这不是一个完整的MESI协议。

两个DSU cluster的L3 cache中的TAG中,是有MESI比特位的,这两个DSU通过ACE/CHI 接口发起的读写是带有MESI信号的,所以他们是支持MESI协议的。

dynamIQ架构同一个core中的L1和L2 cache

dynamIQ架构core中的L1和L2 cache不存在缓存一致性的问题,但有分配和替换策略。

下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之间的替换策略,这部分是硬件定死的,软件不可更改的。

• 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的TRM手册。

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

cache的安全访问

cache中的安全比特;

首先看到core,core中有一个SCR寄存器,寄存器中有一个NS比特位可以表示当前core所处的是安全还是非安全,NS=1非安全,NS=0安全。寄存器的值只能EL3修改,因此只有双系统切换时(安全状态和非安全状态切换时,会经过ATF)才能修改。

core最后要访问memory,中间隔了一个TZC,TZC可以配置memory的权限,是Secure memory还是Non-Secure memory,还有一个的作用就是过滤,如果是非安全的cpu要访问Secure memory会被挡住,无法访问;如果是安全的cpu,TZC都会放行。

看第二步,如果是secure的cpu那么MMU必然就是Secure Transaction Regime,然后就要看entry中的NS比特位,如果NS为1就代表发起Non-Secure Access;如果NS为0,就代表发起Secure Access。;如果是Non-secure的cpu那么使用的MMU就是Non Secure Transaction Regime,下面也永远是Non-Secure Access,不用看NS比特位。

再回看第一步,如果cpu在访问内存时,已经在TLB中命中,就不会经过MMU的翻译,直接进行标号位1的路径,此时TLB的entry中有两个NSbit位,后面的NS就对应了第二步中entry的NS位,二者一致,就决定了接下来访问的安全状态。前面的NS代表了是Secure Transaction Regime还是Non Secure Transaction Regime。

页表entry中的NS比特位在软件中是可以修改的。

一个非安全侧的entry中NS=1,如果给它修改位0,那么可以访问安全的memory可以吗?答案是不可以的,因为是Non Secure Transaction Regime,它就不会看NS比特位,自然还是进行Non Secure Access。

如果在安全侧是secure Transaction Regime,那么访问的内存可以修改NS比特位吗?答案是可以的。

相关推荐
帆仔哟16 分钟前
【农气项目】基于适宜度的产量预报
java
MerlinTheMagic28 分钟前
Spring AI 核心概念
java·人工智能·spring
dadaobusi1 小时前
qemu构建arm环境(AI生成)
arm开发
冼紫菜1 小时前
基于Redis实现高并发抢券系统的数据同步方案详解
java·数据库·redis·后端·mysql·缓存·性能优化
酷ku的森1 小时前
Spring Web MVC入门
spring·mvc
碎梦归途1 小时前
23种设计模式-结构型模式之适配器模式(Java版本)
java·开发语言·jvm·单例模式·设计模式·适配器模式
wkj0011 小时前
JDK版本与Spring Boot版本之间对应关系
java·linux·spring boot
西洼工作室1 小时前
黑马商城-微服务笔记
java·笔记·spring·微服务
异常君1 小时前
MySQL重复数据克星:7种高效处理方案全解析
java·后端·mysql
异常君1 小时前
Spring 定时任务执行一次后不再触发?5 大原因与解决方案全解析
java·后端·spring