1.一文搞懂Cache基本原理
2.计算机组成原理之Cache原理
3.简要介绍Cache替换算法,算算法及几种不同替换算法。法源
4.简单概括Linux内核源码高速缓存原理(图例解析)
5.BlueStore源码分析之Cache
一文搞懂Cache基本原理
理解Cache基本原理,算算法需把握四个核心方面:局部性原理:包括空间局部性和时间局部性。法源空间局部性体现在数据访问的算算法重复性,如数组读写模式;时间局部性则关注循环内数据的法源ys源码频繁访问。
Cache映射方式:涉及全相联、算算法直接映射和组相联映射。法源全相联映射实现灵活的算算法映射关系;直接映射则简单直接,但灵活性受限;组相联映射结合了二者优点,法源通过分组实现。算算法
替换算法:包括随机、法源FIFO、算算法LRU和LFU算法。法源LRU和LFU考虑了数据访问频率,算算法利用计数器实现对近期和近期最少使用的数据优先替换。
Cache写策略:主要解决如何保持Cache和主存数据一致性。写回法、全写法、写分配法和非写分配法各有适用场景,根据Cache命中与否和主存写入策略,cpp 源码实现数据的一致性。
Cache通过在主存与CPU之间提供高速缓冲,显著提高了数据访问速度。结合局部性原理和合理的映射与替换策略,确保了系统的高效运行。在多级Cache架构中,缓存层的优化与协调,进一步提升了整体性能。
计算机组成原理之Cache原理
让我们深入理解计算机组成原理中的关键部分——Cache,它如何运用局部性原则,以及地址映射和替换算法在内存管理中的作用。Cache就像数据的高速缓存,通过字节和块的智能交换,加速了数据的访问速度。基于局部性原理的Cache
Cache的设计核心是基于程序的局部性,无论是读还是写操作,它都试图提前预测并存储最常访问的数据。读取时,首先快速搜索Cache,若未找到,源码售价就从主存获取数据并将其存入Cache以供后续快速访问。写操作则有写穿和写回两种策略,写穿意味着直接写入主存,而写回则是写入Cache后再回写到主存。地址映射的艺术
Cache地址映射涉及多个组件:Tag(用于唯一标识)、Index(指定位置)和Data(存储数据)。Cache的结构由行、Tag、Data、Valid(表示缓存是否有效)和Dirty(表示缓存是否需要写回)等部分构成。当数据被请求时,通过Tag比较,判断数据是否在Cache内,从而进行存取操作。 两种常见的映射方式:全相联映射如同万能钥匙,将主存块灵活映射到Cache的任意一行,而直接相联映射则将主存块分区,直接对应Cache的特定行。全相联示例中,0x1e的letnet 源码访问可能会导致其他未命中的地址被写入空行,更新Cache状态;而直接相联映射则将主存地址转换为三维,确保精确命中。组相联与替换算法
在容量有限的Cache中,当满载时,就需要依靠替换算法来决定淘汰哪些行。组相联映射通过三维地址,巧妙地在容量和效率之间找到平衡。例如,当处理一系列数据访问,如, , , , 时,先进先出(FIFO)算法会根据访问顺序淘汰最旧的数据,而最不常用法则(LFU)则会优先淘汰被访问次数最少的行。最近最少使用(LRU)法则则是根据最近的访问历史进行替换,淘汰计数较大但最近未使用的行。简要介绍Cache替换算法,及几种不同替换算法。
Cache替换算法在提高缓存系统效率中起着至关重要的作用。不同的替换算法设计旨在提高缓存的命中率,从而优化数据访问速度。以下是foxbase 源码几种常见的Cache替换算法:
1. LRU(Least Recently Used)算法:
此算法基于这样一个原则,即最长时间未被访问的数据块最不可能被频繁使用。因此,当需要替换Cache中的数据时,LRU算法会选择最久未使用的数据块移出Cache。
2. LFU(Least Frequently Used)算法:
与LRU算法不同,LFU算法倾向于替换那些被访问次数最少的数据块。这种方法假设频繁访问的数据块更有可能在未来被再次访问。
3. Pitkow/Recker算法:
这是一种考虑了时间因素的替换策略。如果Cache中的所有数据都是在同一天缓存的,那么算法会选择最大的数据块替换。如果Cache中包含不同日期的数据,则按照LRU算法进行替换。
4. Size算法:
这种算法简单地将最大的数据块替换出Cache。这种方法不考虑数据的访问频率或最近使用情况。
5. LRU-MIN算法:
旨在减少因替换而产生的数据块数量。它首先寻找大小至少与待缓存数据块相同的Cache条目,并按照LRU规则替换。如果找不到足够大的条目,它则从大小至少为待缓存数据块一半的条目中选择。
6. LRU-Threshold算法:
类似于LRU算法,但它设定了一个阈值,大于这个阈值的数据块不能被缓存。这有助于控制Cache的大小,防止其无限增长。
这些替换算法各有优劣,它们的选择和应用取决于特定系统的需求和性能目标。
简单概括Linux内核源码高速缓存原理(图例解析)
高速缓存(cache)概念和原理涉及在处理器附近增加一个小容量快速存储器(cache),基于SRAM,由硬件自动管理。其基本思想为将频繁访问的数据块存储在cache中,CPU首先在cache中查找想访问的数据,而不是直接访问主存,以期数据存放在cache中。
Cache的基本概念包括块(block),CPU从内存中读取数据到Cache的时候是以块(CPU Line)为单位进行的,这一块块的数据被称为CPU Line,是CPU从内存读取数据到Cache的单位。
在访问某个不在cache中的block b时,从内存中取出block b并将block b放置在cache中。放置策略决定block b将被放置在哪里,而替换策略则决定哪个block将被替换。
Cache层次结构中,Intel Core i7提供一个例子。cache包含dCache(数据缓存)和iCache(指令缓存),解决关键问题包括判断数据在cache中的位置,数据查找(Data Identification),地址映射(Address Mapping),替换策略(Placement Policy),以及保证cache与memory一致性的问题,即写入策略(Write Policy)。
主存与Cache的地址映射通过某种方法或规则将主存块定位到cache。映射方法包括直接(mapped)、全相联(fully-associated)、一对多映射等。直接映射优点是地址变换速度快,一对一映射,替换算法简单,但缺点是容易冲突,cache利用率低,命中率低。全相联映射的优点是提高命中率,缺点是硬件开销增加,相应替换算法复杂。组相联映射是一种特例,优点是提高cache利用率,缺点是替换算法复杂。
cache的容量决定了映射方式的选取。小容量cache采用组相联或全相联映射,大容量cache采用直接映射方式,查找速度快,但命中率相对较低。cache的访问速度取决于映射方式,要求高的场合采用直接映射,要求低的场合采用组相联或全相联映射。
Cache伪共享问题发生在多核心CPU中,两个不同线程同时访问和修改同一cache line中的不同变量时,会导致cache失效。解决伪共享的方法是避免数据正好位于同一cache line,或者使用特定宏定义如__cacheline_aligned_in_smp。Java并发框架Disruptor通过字节填充+继承的方式,避免伪共享,RingBuffer类中的RingBufferPad类和RingBufferFields类设计确保了cache line的连续性和稳定性,从而避免了伪共享问题。
BlueStore源码分析之Cache
BlueStore通过DIO和Libaio直接操作裸设备,放弃了PageCache,为优化读取性能,它自定义了Cache管理。核心内容包括元数据和数据的Cache,以及两种Cache策略,即LRU和2Q,2Q是默认选择。
2Q算法在BlueStore中主要负责缓存元数据(Onode)和数据(Buffer),为提高性能,Cache被进一步划分为多个片,HDD默认5片,SSD则默认8片。
BlueStore的元数据管理复杂,主要分为Collection和Onode两种类型。Collection存储在内存中,Onode则对应对象,便于对PG的操作。启动时,会初始化Collection,将其信息持久化到RocksDB,并为PG分配Cache。
由于每个BlueStore承载的Collection数量有限(Ceph建议每个OSD为个PG),Collection结构设计为常驻内存,而海量的Onode则仅尽可能地缓存在内存中。
对象的数据通过BufferSpace进行管理,写入和读取完成后,会根据特定标记决定是否缓存。同时,内存池机制监控和管理元数据和数据,一旦内存使用超出限制,会执行trim操作,丢弃部分缓存。
深入了解BlueStore的Cache机制,可以参考以下资源: