快速链接:
.
个人博客笔记导读目录(全部)
- ARMv8/ARMv9架构精选系列–目录
- ARMV8/ARMV9/Trustzone/TEE安全课程
ARM 架构刚开始开发时,处理器的时钟速度和内存的访问速度大致相似。今天的处理器内核要复杂得多,并且时钟频率可以快几个数量级。然而,外部总线和存储设备的频率并没有达到同样的程度。可以实现可以与内核以相同速度运行的小片上 SRAM块,但与标准 DRAM 块相比,这种 RAM 非常昂贵,标准 DRAM 块的容量可能高出数千倍。在许多基于 ARM 处理器的系统中,访问外部存储器需要数十甚至数百个内核周期。
缓存是位于核心和主内存之间的小而快速的内存块。它在主内存中保存项目的副本。对高速缓冲存储器的访问比对主存储器的访问快得多。每当内核读取或写入特定地址时,它首先会在缓存中查找。如果它在高速缓存中找到地址,它就使用高速缓存中的数据,而不是执行对主存储器的访问。通过减少缓慢的外部存储器访问时间的影响,这显着提高了系统的潜在性能。通过避免驱动外部信号的需要,它还降低了系统的功耗
DSU-AE 实现了系统控制寄存器,这些寄存器对cluster中的所有core都是通用的。 可以从cluster中的任何core访问这些寄存器。 这些寄存器提供:
L3 cache
需要参考ARM文档,其实每一个core的cache大小都是固定的或可配置的。
思考 :什么是Set、way、TAG 、index、cache line、entry?
读分配(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和主存的数据可能不一致
对于cacheable属性,inner和outer描述的是cache的定义或分类。比如把L1/L1看做是inner,把L3看做是outer
通常,内部集成的cache属于inner cache,外部总线AMBA上的cache属于outer cache。例如:
然后我们可以对每类cache进行单独是属性配置,例如:
对于shareable属性,inner和outer描述的是cache的范围。比如inner是指L1/L2范围内的cache,outer是指L1/L2/L3范围内的cache
以下再次对Inner/Outer属性做了一个小小的总结:
如果将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 和 cluster0的L2 cache,不会缓存到其它cache中
如果将block的内存属性配置成 inner-shareable, 那么core0访问该内存时,数据只会缓存到core 0和core 1的L1 d-cache中, 也会缓存到clustor0的L2 cache,不会缓存到clustor1中的任何cache里。
如果将block的内存属性配置成 outer-shareable, 那么core0访问该内存时,数据会缓存到所有cache中
Non-cacheable | write-through cacheable |
write-back cacheable |
|
---|---|---|---|
non-shareable | 数据不会缓存到cache (对于观察则而言,又相当于outer-shareable) |
Core0读取时,数据缓存的到Core0的L1 d-cache 和 cluster0的L2 cache, 如果core0和core1都读写过该内存,且在core0 core1的L1 d-cache中都缓存了该内存。那么core0在读取数据的时候,core0的L1 Dcache会更新,但core 1的L1 Dcache不会更新 | 同左侧 |
inner-shareable | 数据不会缓存到cache (对于观察则而言,又相当于outer-shareable) |
Core0读取时,数据缓存的到Cluster0中所有cache | 同左侧 |
outer-shareable | 数据不会缓存到cache (对于观察则而言,又相当于outer-shareable) |
Core0读取时,数据缓存的到所有cache | 同左侧 |
MMU由TLB和Address Translation 组成:
cache又分为;
先讨论一个简单的内存读取,单核的. 如LDR X0, [X1], 假设X1指向main memory,且是cacheable.
(1)、Core先去L1 cache读取,hit了,直接返回数据给Core
(2)、Core先去L1 cache读取,miss了,然后会查询L2 cache,hit了,L2的cache数据会返回Core,还会导致这个cache line替换到L1中的某一行cache line
(3)、如果L1 L2都是miss,那么data将会从内存中读取,缓存到L1和L2,并返回给Core
接着我们再看一个复杂的系统,不考虑L3,多核的.
(1)、如果是inclusive cache,那么数据将会被同时缓存到L1和L2
(2)、如果是exclusive cache,那么数据只缓存到L1,不会缓存到L2
假设一个4路相连的cache,大小64KB, cache line = 64bytes,那么 1 way = 16KB,indexs = 16KB / 64bytes = 256 (注: 0x4000 = 16KB、0x40 = 64 bytes)
0x4000 – index 0
0x4040 – index 1
0x4080 – index 2
…
0x7fc0 – index 2550x8000 – index 0
0x8040 – index 1
0x8080 – index 2
…
0xbfc0 – index 255
例如 A76
L1 i-cache :64KB,4路256组相连,cache line为64bytes
TLB i-cache :全相连,支持4KB, 16KB, 64KB, 2MB,32M的页
L1 d-cache :64KB,4路256组相连,cache line位64bytes
TLB d-cache :全相连,支持4KB, 16KB, 64KB, 2MB,512MB的页
L2 cache :8路相连的cache,大小可选128KB, 256KB, or 512KB
Each line in the cache includes:
• A tag value from the associated Physical Address.
• Valid bits to indicate whether the line exists in the cache, that is whether the tag is valid.
Valid bits can also be state bits for MESI state if the cache is coherent across multiple cores.
• Dirty data bits to indicate whether the data in the cache line is not coherent with external memory
• data
那么TAG里又都有什么呢??(S13 才会说这里的TAG等于物理地址里的TAG)
如下以A78为例,展示了TAG里都有什么
先使用index去查询cache,然后再比较TAG,比较tag的时候还会检查valid标志位
什么时候需要软件维护cache:
(1)、当有其它的Master改变的external memory,如DMA操作
(2)、MMU的enable或disable的整个区间的内存访问,如REE enable了mmu,TEE disable了mmu.
针对第(2)点,cache怎么和mmu扯上关系了呢?那是因为:
mmu的开启和关闭,影响了内存的permissions, cache policies
{, }
linux/arch/arm64/mm/cache.S
linux/arch/arm64/include/asm/cacheflush.h
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)
A76
L1 i-cache :64KB,4路256组相连,cache line为64bytes
L1 d-cache :64KB,4路256组相连,cache line为64bytes
L2 cache :8路相连的cache,大小可选128KB, 256KB, or 512KB
L1 TLB i-cache :48 entries, 全相连,支持4KB, 16KB, 64KB, 2MB,32M的页
L1 TLB d-cache : 48 entries,全相连,支持4KB, 16KB, 64KB, 2MB,512MB的页
L2 TLB cache : 1280 entries, 5路组相连
L3 cache
cache size可选 : 512KB, 1MB, 1.5MB, 2MB, or 4MB. cache line = 64bytes
1.5MB的cache 12路组相连
512KB, 1MB, 2MB, and 4MB的caches 16路组相连
A78
L1 i-cache :32或64KB,4路组相连,cache line为64bytes , VIPT
L1 d-cache : 32或64KB,4路组相连,cache line为64bytes, VIPT
L1 TLB i-cache :32 entries, 全相连,支持4KB, 16KB, 64KB, 2MB,32M的页
L1 TLB d-cache : 32 entries,全相连,支持4KB, 16KB, 64KB, 2MB,512MB的页
L2 TLB cache : 1024 entries, 4路组相连
L3 cache
cache size可选 : 512KB, 1MB, 1.5MB, 2MB, or 4MB. cache line = 64bytes
1.5MB的cache 12路组相连
512KB, 1MB, 2MB, and 4MB的caches 16路组相连
ID Register
CTR_EL0, Cache Type Register
对于 DynamIQ架构
Bus Transactions: