[A-02] ARMv8/ARMv9-Cache的结构设计(VIVT-PIPT-VIPT)

ver 0.2
在这里插入图片描述

更多精彩内容,请关注公众号

前言

前文中已经介绍了Cache的基本结构、相关概念、以及Cache和主存的映射关系。本文将更加深入对cache的工作机制进行分析,首先明确在CPU是如何使用Cache的,Cache和主存到底是如何通过虚拟地址和还是物理地址进行映射的,映射的过程中是否存在问题等等。
同样本文中没有特殊说明,Cache中的数据包括指令和被指令操作的数据。

正文

Cache的工作方式

前文更多的是讲述Cache的作用,线条还是比较粗糙,本节我们把视角拉高一些,从处理器的角度分析一下Cache在PE工作中启到的作用。
处理器工作的时候,访问主存使用的是虚拟地址的编码方式。前文中也已经讲过,cache中的数据其实就是主存中数据的副本。主存中的数据编码方式是以字节为单位,而Cache中的数据编址是以Cache Line(一般为64字节)为单位,这样Cache和内存中的数据进行映射就需要一个过程,又因为作为数据的访问者CPU使用虚拟地址进行数据的访问,那么自然这个过程的参与者就变成了PE、MMU、Cache、主存,如何通过虚拟地址进行串联的过程,这里我们通过一个经典的Cache架构加以说明,如图1-1所示。
在这里插入图片描述

图1-1 Cache的经典架构

我们对上面这个架构做一下拆解,其实就是一个寻找TAG、Index、Offset之旅:
(1) S-1 任何时候,CPU在访问主存的时候永远是使用虚拟地址的。内存管理是个很复杂的课题,我们后续会有专门的文章进行讨论。而支持通过虚拟地址方式访问是现代处理器的基本能力。可以这么理解虚拟地址给软件用的,物理地址是给硬件用的,虚拟地址和物理地址之间有一个映射的关系,不过这个映射是以页或者块为单位的,最少小映射颗粒度是4k空间。这块就不展开讲了,后面会有文章专门讨论。
(2) 处理器在访问存储器时,会把虚拟地址同时传递给 TLB (S-2)和Cache高速缓存(S-6)。 TLB (Translation Lookaside Buffer)是一个用于存储虚拟地址到物理地址转换的小缓存,处理器先使用有效页帧号(Effective Page Number, EPN)在 TLB 中查找最终的实际页帧号(Real Page Number, RPN)。假设发生 TLB 命中(TLB hit)(S-3),就会很快获得合适的 RPN ,并得到相应的物理地址(Physical Address , PA)。
到这里我们简单回顾下寻址一个cache line的3要素:TAG、Index、Offset。既然,我们已经锁定了物理地址,那么至少TAG到这里我们是可以确定了的。
(3) 同时,处理器通过高速缓存编码地址的索引(index )域可以很快找到相应的高速缓存行对应的组Set(S-3)。但是这里的高速缓存行的数据不一定是处理器所需要的,因此有必要进行一些检查,将高速缓存行中存放的标记域TAG和通过MMU 转换得到的物理地址的标记域进行比较。如果相同并且状态位匹配,就会发生高速缓存命中(cache hit)(S-8),处理器通过字节选择与对齐(byte select and align)部件,就可以获取所需要的数据。这个过程就是把S-6过来的Index分发给所有的Way的Set然后比较TAG,再比较TAG的有效位,如果都匹配说明数据在cache且有效。就可以把cache line上的数据整体取出来了。
(4) 此时通过TAG和Index已经取出了Cache Line的数据,但是CPU其实想要的也许就是其中的几个字节的数据,那么就通过S-9传过来的Offset做更精细化的自己寻址就可以了。到这里,我们就顺利的给CPU返回它想要的数据了。

例外的情况:
(5) 如果发生高速缓存未命中(cache miss),处理器需要用物理地址进一步访问主存储器来获得最终数据,数据也会填充到相应的高速
缓存行中。也就是经过TAG和Index进行比较判断出,想要的数据没有在Cache中,因为此时系统已经了主存数据所在的物理地址,直接按照既定的替换策略,将数据经过L3-Cache->L2-Cache->L1 Cache(S-7)加载到Cache,然后重复过程上述(3)(4)也达到了CPU的目的。
(6) 如果其间发生 TLB 未命中(TLB miss)(S-4),将会带来一系列严重的系统惩罚,处理器需要查询页表。那么此时,MMU就要做虚拟地址和物理地址映射,其实就是到页表中找到对应分配好的页中数据的物理地址(之前没有分配的话,说明想要的数据主存中也有没有就要抛出异常先将数据从系统外部加载到主存),然后将这个物理地址和数据经过S-5和(5)中的过程,然后就让CPU得到它想要的数据。

上面这个过程,大家如果接受有难度,可以不用着急,后面讲到ARM内存管理的时候还会仔细拆解。这里先关注总结2个点:
(1) TAG 在这里是是通过物理地址算出来的。
(2) Index是通过虚拟地址算出来的。
(3) 通过虚拟Index和物理TAG的形式我们寻址到了Cache Line。
这就是缓存实际的组织形式之一VIPT,实际上Cache还有其他的组织形式,一个CPU中不同level的cache可以支持不同的组织形式。本文下面的章节,我们就来介绍Cache的类型。

Cache类型

这里我们结合一款具体的ARM处理器架构来介绍一下Cache的分类,如图1-2所示。
ARM-710

图1-2 Cortex-A710 Core Components

通过Cortex-A710的block图,我们可以清晰看到,ARM设计了两级Cache结构,其中L1层还对Cache做了细分(指令和数据分离)。下面看一下这两级Cache的具体特征,如图1-3、1-4、1-5所示。
L1-I-F

图1-3 L1 Instruction Cache Features

L1-D-F

图1-4 L1 Data Cache Features

L2-F

图1-5 L2 Cache Features

Cortex-A710的Cache的Feature可以简单总结一下:
(1) Cache Size 为 32KB、64KB、256KB、512KB;
(2) Cache Line length都为64bytes;
(3) 都是组多路组关联的方式(4 or 8 ways set associative);
(4) Index和Tag的类型分别是VIPT和PIPT。
(5) 替换策略为LRU 或者 动态地调整替换策略。

Cache的详细结构

Feature中的(1)(2)(3)前面的文章我们已经充分讨论过了,替换的策略我们会再开一片文章讨论一下,这里我们会重点讨论一下Index和Tag的类型,借此也讨论清楚Cache的结构。前面讲述VIPT类型的Cache的工作流程,这里们看到ARM-Core中的cache还有另外一种组织形式PIPT,要讨论讲清楚这两种Cache类型,我们还是要结合的具体结构,如图1-6所示。
cache'-struct

图1-6 64KB 4-way set associative data cache

这是ARM手册中一个比较经典的例子(手册中的例子貌似有点错误,这里也希望大家一起思考指正),64KB-L1 data cache,分成4路,采用组关联的方式,每行的cache line的长度或者size为64字节。
(1) 高速缓存的总大小为 64KB ,并且是 4 路的,所以每一路的大小为 16KB(way_size = 64KB/ 4 = 16KB) 。
(2) 高速缓存行的大小为 64 字节,所以每一路包含的高速缓存行数量如下num_cache_line = 16KB/64B = 256。

Offset
这里offset为地址编码这哪个Bit[0:5]总计6位,其中Bit[2:5]共计4位可以用来寻址0~15共计16个字,Bit[0:1]可以对字中的字节进行寻址,最终实现的效果就是可以实现Cache Line中的64字节寻址。

Index
Bit[6:13] 共8位用于在索引域中选择每一路上的高速缓存行,也就是Index可以实现在一路cache中进行256行的寻址。因为cache采用的是组关联的方式,也就是说这里Index可以实现这4路256组的寻址。

TAG
Bit[14:43]共30位用作标记域。

V & D
当我们通过主存的地址编码确认了Offset、Index、TAG之后就可以在cache中锁定了CPU想要的数据了,但是此时还不是胜利的时候,还需要检查数据所在的Cache Line的两个标志位:V,D。这两个标志位的作用,我们直接引用手册的描述:

• 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.

图1-6虽然已经很详细的描述了Cache的结构,但是还是有一个点没有讲清楚,就是我们前面章节举例中提到的一点,CPU使用的虚拟地址采用什么样的方式和Cache中的TAG、Index做映射,比如例子中使用的是VIPT(使⽤虚拟地址的索引域和物理地址的标记域)的方式,还有哪些方式,下面来一一讨论一下,因为不同的映射方式对应的CPU-Core内部硬件电路(CPU的架构)也是不一样的。以ARM为例,从早期到现在总共使用了3中映射技术:虚拟高速缓存 (VIVT) 、物理标记的虚拟高速缓存 (VIPT) 、物理高速缓存 (PIPT).

VIVT
VIVT(Virtual Index Virtual Tag) 使⽤虚拟地址的索引域和虚拟地址的标记域,相当于虚拟⾼速缓存,早期的处理器采用的就是这种方式。这种方式就是把PE传递过来的虚拟地址直接切成三段分别代表TAG、Index、Offset(如图1-7所示),然后对Cache进行寻址,命中则直接返回数据,失败则需要讲虚拟地址转换成物理地址,然后寻址主存储器然后将数据加载到Cache再返回给PE。
VIVT

图1-7 VIVT的设计模式

一个VA的地址可以映射到任意物理地址,VIVT的cache不需要经过MMU译码,直接会被拆分成TAG(V)和Index(V),以页为4K为例,不论怎么切分也就是(S-1、S-2、S-3)这三种场景。这样设计的好处是架构简单,但是会引入两个问题:歧义和别名。
(1)歧义(ambiguity):
当不同的数据在⾼速缓存当中有相同的index、tag时就会出现歧义,index、tag作为⾼速缓存判断数据的仅有的⽅式,这就意味着数据的访问就可能出现错误,这就是歧义。我们来看一个具体的场景,如图1-8所示。
歧义

图1-8 VIVT的歧义场景

当一个进程的代码经过编译器编译之后,在进程的可执行文件中是通过虚拟地址标识编译后的指令和数据的,例如进程a、b、c通过相同的虚拟地址0x354标识一个变量i。那么在进程a执行之后,变量i已经加载进cache,通过虚拟地址0x354就可以使用访问变量i。如果此时切换到进程b,此时如果不经过任何处理,直接还是使用0x354去访问数据就会造成歧义,就是此时PE实际上想访问的时候进程b的变量i,但是实际上访问的是进程a的变量i。解决这个问题的⽅法也很简单就是在task B访问之前做⼀个cache flush的操作即可,这样task B访问时就会cache miss,然后从主存储器当中获取数据,但是带来的问题时cache的局部性被破坏,cache命中率降低,⼤量的程序切换就会造成性能的变慢。

(2)别名(aliasing):
当使⽤⼀个以上不同的虚拟地址来替代相同的物理地址时就会发⽣别名现象。还是结合具体场景,如图1-9所示。
别名

图1-9 VIVT的重名场景

如果⼀个进程将同⼀个共享存储区域映射到它的地址空间中两个不同的虚拟地址上,或者两个不同进程在他们各⾃的地址空间中使⽤了同⼀个共享存储区域都会出现别名问题。简单来说就是: 当不同的虚拟地址映射相同的物理地址,⽽这些虚拟地址的index、tag不同,当进程A运行的时候,共享的区域会被映射进Cache,此时进程B执行,由于是另外一个进程使用不同的虚拟地址访问进程A共享的内存,那么此时会发生Cache Miss,那么系统还需要再加载一次,那么映射的同⼀个物理地址的数据被加载到不同的cache line中就在访问时就会出现别名问题。当一个物理地址的内容可以出现在多个cache line中,当系统改变了虚拟地址到物理地址映射时,需要清洗(clean)和无效(invalidate)这些cache,导致系统性能下降。VIVT造成的歧义(ambiguity)和重名(aliasing)两个问题的维护成本极高,最难管理,现在基本没有硬件还在使用了。

PIPT
PIPT(Physical Index Physical Tag): 使⽤物理地址的索引域和物理地址的标记域,相当于物理⾼速缓存。这种设计模式下就不存在歧义和别名问题了,如图1-10所示。
PIPT

图1-10 PIPT的设计模式

我们还是结合具体场景来说明PIPT类型的cache。在不同进程虚拟地址空间转换成物理地址在系统当中是唯⼀的,所以tag、index是唯⼀的。而此种模式下,处理器每次要访问主存之前都会先把虚拟地址转化成物理地址,然后用物理地址再去做切分,TAG和Index还是唯一的。Tag是唯⼀的也就解决了歧义问题,index的唯⼀⽤于完全解决别名问题。ARM Cortex-A系列处理器的数据cache开始采用PIPT的方式。我们也可以吧PIPT理解为虚拟地址到TAG、Index的转化硬件化了,但是付出的代价是PIPT变得非常复杂。

VIPT
VIPT(Virtual Index Physical Tag) ,使⽤虚拟地址的索引域和物理地址的标记域。由于使用VIVT的模式Cache会造成歧义和别名的问题,而为了解决这两个问题,需要通过不断冲刷和清洗Cache才能解决,但是频繁的冲刷和清洗Cache会造成性能问题。而PIPT的硬件逻辑不但复杂,而且每次都要进行物理地址翻译,然后才能进行TAG和Index的映射,这也会早晨一定的性能开销。那么就继续改进Cache的设计,引入优化后VIPT的设计模式,将TAG通过物理地址去做映射,而Index直接使用虚拟地址。
(1) VIPT的工作模式前面章节,我们已经讨论过了。这里我们看一下,VIPT如何解决歧义问题。歧义是因为不同进程可能存在相同虚拟地址导致的index、tag造成了cache的歧义。每个进程的虚拟地址空间转换成⼀个明确的物理地址,在系统当中物理地址是唯⼀的,所以不管你虚拟地址是否相同,物理地址是不可能相同的,tag取⾃物理地址,那么tag就不可能相同,所以VIPT来说歧义问题就不存在了。
(2)别名是因为不同虚拟地址映射到了相同物理地址,导致该物理地址的数据会被加载到多个CacheLine中。那么采用VIPT的cache会不有别名问题呢?这个需要结合具体场景讨论,如图1-11所示。
VIPT

图1-11VIPT的场景

如图1-11所示,我们前面已经大概的讨论过物理内存和虚拟内存的话题,我们知道物理内存和虚拟内存是以页为单位进行一一映射的。这里我们假设页的Size被初始化为4k也就是需要Bit[0:11]共12位作为Page内部的寻址空间,由于PA和VA是以页为最小颗粒度进行映射,那么PA(Bit[0:11]) 等于VA(Bit[0:11]),需要译码时,MMU只需要将PA-H和VA-H做映射就可以了,也就是说PA-H和VA-H是不相等的。这些都是前提条件,下面我们分三种情况进行讨论:
(1) S-1,此时Index长度和Offset长度刚好是12位宽也就是VA和PA低端地址Bit[0:11]的寻址空间,由于PA(Bit[0:11]) 等于 VA(Bit[0:11]),所以即便是使用VA的低端地址Bit[0:11]的一部分做Index,实际上和PA的低端地址Bit[0:11]的一部分是重合的,例如使用VA(Bit[9:11])做Index的话实际上VA(Bit[9:11])等于PA(Bit[9:11]),那么此时Index(V) 等于 Index§ 。此时TAG区域直接使用PA-H的高端地址区域,那么最后呈现的效果实际上和PIPT是一样的,保证了TAG的唯一性和Index的唯一性。具象化一下帮助大家理解:

• 假如我们有一个数据i存储在物理地址PA,这个变量i同时共享给TaskA和TaskB访问,进程只能使用虚拟地址,假设为VA(TaskA)和VA(TaskB)
PA: 0b<63:32 as 0> 0000 0000 0000 0000 0101 0101 0101 0101
VA(TaskA) : 0b<63:32 as 0> 0000 0000 0000 0000 1111 0101 0101 0101
VA(TaskB) : 0b<63:32 as 0> 0000 0000 0000 0000 1110 0101 0101 0101
• 通过观察可以推导出条件一:PA(0:11) 等于VA(TaskA)(0:11) 等于 VA(TaskB)(0:11)。
• 此时CPU-Core执行TaskA的代码,要访问变量i的时候,会将VA(TaskA)提供给MMU译码成PA,那么此时会用PA(Bits[12:63])作为TAG、TaskA的VA(Bits[x:11])作为Index,检查cache,如果命中直接返回,如果未命中那么就从主存加载数据到Cache。
• 现在由于调度系统的作用讲CPU控制权交给TaskB,TaskB也要方位共享变量i,CPU-Core会将VA(TaskB)提供给MMU译码成PA(因为是共享变量,所以译码后结果都是指向PA),那么此时也还是会用PA(Bits[12:63])作为TAG、TaskB的VA(Bits[x:11])作为Index{根据条件一,此时TaskB的VA(Bits[x:11]) 等于 TaskA的VA(Bits[x:11])},因为之前已经加载过TAG(PA[12::63]) + Index(VA[x:11])到Cache Line,所以会直接cache命中,不会出现重复加载共享变量i到Cache的情况,也就避免了别名问题。

(2) S-2,通过S-1的分析,我们知道PA(Bit[0:11]) 等于 VA(Bit[0:11]),此时TAG的区域变大挤占了一部分Page内部的寻址空间也就是VA(Bit[0:11])的一部分空间,那么并不影响Index的唯一性,例如此时TAG占用了Page区域的11位和10位,也就是VA(Bit[10:11]),那么此时Index可能的选择是VA(Bits[7:9]),由于VA(Bits[7:9])等于PA(Bits[7:9]),那么此时Index还是唯一的。而是TAG的区域变成了PA(Bits[10:63))也是唯一的。那么这种情况下最好呈现的效果和S-1是一样的,保证了TAG的唯一性和Index的唯一性。具象化一下帮助大家理解:

• 假如我们有一个数据i存储在物理地址PA,这个变量i同时共享给TaskA和TaskB访问,进程只能使用虚拟地址,假设为VA(TaskA)和VA(TaskB)
PA: 0b<63:32 as 0> 0000 0000 0000 0000 0101 0101 0101 0101
VA(TaskA) : 0b<63:32 as 0> 0000 0000 0000 0000 1111 0101 0101 0101
VA(TaskB) : 0b<63:32 as 0> 0000 0000 0000 0000 1110 0101 0101 0101
• 通过观察可以推导出条件一:PA(0:11) 等于VA(TaskA)(0:11) 等于 VA(TaskB)(0:11)。
• 此时CPU-Core执行TaskA的代码,要访问变量i的时候,会将VA(TaskA)提供给MMU译码成PA,那么此时会用PA(Bits[10:63])作为TAG、TaskA的VA(Bits[x:9])作为Index,检查cache,如果命中直接返回,如果未命中那么就从主存加载数据到Cache。
• 现在由于调度系统的作用讲CPU控制权交给TaskB,TaskB也要方位共享变量i,CPU-Core会将VA(TaskB)提供给MMU译码成PA(因为是共享变量,所以译码后结果都是指向PA),那么此时也还是会用PA(Bits[10:63])作为TAG、TaskB的VA(Bits[x:9])作为Index{根据条件一,此时TaskB的VA(Bits[x:9]) 等于 TaskA的VA(Bits[x:9])},因为之前已经加载过TAG(PA[10::63]) + Index(VA[x:9])到Cache Line,所以会直接cache命中,不会出现重复加载共享变量i到Cache的情况,也就避免了别名问题

(3) S-3,情况就复杂了,因为Index挤占了部分VA的空间。此时TAG的选择可能是PA(Bits[13:63]),这是因为VA的第12位被挤占了,那么自然PA的第12位也不能用来当成TAG的一员了,此时Index变成了VA(Bit[12])加上VA(Bit[x:11]),此时VA(Bit[x:11])和PA(Bit[x:11])还是相同的,但是VA(Bit[12])却会有两种选择0或者1,也就不能保证Index的唯一性,也就是还是会有别名问题的存在。具象化一下帮助大家理解:

• 假如我们有一个数据i存储在物理地址PA,这个变量i同时共享给TaskA和TaskB访问,进程只能使用虚拟地址,假设为VA(TaskA)和VA(TaskB)
PA: 0b<63:32 as 0> 0000 0000 0000 0000 0101 0101 0101 0101
VA(TaskA) : 0b<63:32 as 0> 0000 0000 0000 0000 1111 0101 0101 0101
VA(TaskB) : 0b<63:32 as 0> 0000 0000 0000 0000 1110 0101 0101 0101
• 通过观察可以推导出条件一:PA(0:11) 等于VA(TaskA)(0:11) 等于 VA(TaskB)(0:11)。
• 此时CPU-Core执行TaskA的代码,要访问变量i的时候,会将VA(TaskA)提供给MMU译码成PA,那么此时会用PA(Bits[13:63])作为TAG、TaskA的VA(Bits[x:12])作为Index{注意:此时Index使用的VA(TaskA)的Bit[12]为1},检查cache,如果命中直接返回,如果未命中那么就从主存加载数据到Cache。
• 现在由于调度系统的作用讲CPU控制权交给TaskB,TaskB也要方位共享变量i,CPU-Core会将VA(TaskB)提供给MMU译码成PA(因为是共享变量,所以译码后结果都是指向PA),那么此时也还是会用PA(Bits[13:63])作为TAG、TaskB的VA(Bits[x:12])作为Index{根据条件一,此时TaskB的VA(Bits[x:11]) 等于 TaskA的VA(Bits[x:11]),但是此时Index使用的VA(TaskB)的Bit[12]为0,因此Index和之前TaskA访问cache时Task用的Index是不相等的},显然TAG(PA[13:63]) + Index(VA[x:12])到Cache Line中寻址不会发生cache命中,因此要重复加载共享变量i到Cache的情况,也就发生了别名问题,也就是说这种情况下不能避免发生别名问题。

优化
通过前面的叙述,VIPT还是不能完全避免别名问题,但是VIPT寻址Cache的过程中会少一次做虚拟地址到物理地址再到Index的过程,所以效率上还是会别PIPT会高一些,CPU的微架构设计也会得到简化,所以Cortex-A710的L1-Cache采用VIPT的设计。怎么做到的呢?其实就是设计的时候避免采用S-1或者S-2的逻辑就可以了,就能得到微架构简化,结果正确,而又将性能推到极致的结果。那么我们仍然具象化一个场景,帮助大家理解:

• Cache Size 为64KB,分成4-way,那么每路为16KB = 64KB/4
• 每行Cache Line能够容纳64(2的6次方)字节的数据的话,那么每路就有 16K / 64 = 256(2的8次方)
• 此时系统PageSize配置为16KB(Bits[0:13])的话,正好可以满足Index和Offset的位长6+8 = 14。
• 虚拟地址转换后的PA(Bits[14:63])做TAG。
•上面的组合就可以满足使用VIPT作为Cache的结构设计,又可以避免发生别名的情况。

当然,我们配置Page Granule为4k或者64k的时候,为了避免别名,就要调整Cache的路数或者每行Cache Line的size了。

我们来看一下AArch64支持多少种PageSize的配置,如图1-12所示:
Page Granule

图1-12 AArch64 Page Granule

结语

本文,我们花了很大的精力来解释Cache的详细构造。通过许多具体的场景,具体介绍了Cache的构造,Cache的类型,并且说明了各种类型的优点和缺点。本文的难点是对于Cache设计中的歧义和别名问题,我们也做了详细的分析,希望能对大家有所帮助。Cache的内容还没完,下面我们会继续讲解Cache使用中的一些策略相关的点。

在这里插入图片描述

更多精彩内容,请关注公众号

Reference

[01] <DDI0487K_a_a-profile_architecture_reference_manual.pdf>
[02] <DEN0024A_v8_architecture_PG.pdf>
[03] <80-LX-MEM-yk0008_CPU-Cache-RAM-Disk关系.pdf>
[04] <80-ARM-ARCH-HK0001_一文搞懂CPU工作原理.pdf>
[05] <80-ARM-MM-Cache-wx0003_Arm64-Cache.pdf>
[06] <80-ARM-MM-HK0002_一文搞懂cpu-cache工作原理.pdf>
[07] <80-MM-yd0001_Caches-From-a-Mostly-OS-Software-Perspective.pdf>
[08] <80-MM-yd0002_Improving-Kernel-Performance-by-Unmapping-the-Page-Cache.pdf>
[09] <arm_cortex_a710_core_trm_101800_0201_07_en.pdf>
[10] <DDI0608B_a_armv9a_supplement_RETIRED.pdf>
[11] <arm_cortex_a520_core_trm_102517_0003_06_en.pdf>
[12] <arm_cortex_a720_core_trm_102530_0002_05_en.pdf>
[13] <79-LX-LK-z0002_奔跑吧Linux内核-V-2-卷1_基础架构.pdf>

Glossary

SRAM - Static Random-Access Memory
DRAM - Dynamic Random Access Memory
SSD - Solid state disk
HDD - Hard Disk Drive
SOC - System on a chip
AMBA - Advanced Microcontroller Bus Architecture 高级处理器总线架构
TLB - translation lookaside buffer(地址变换高速缓存)
VIVT - Virtual Index Virtual Tag
PIPT - Physical Index Physical Tag
VIPT - Virtual Index Physical Tag

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值