关于cache line

一个L1 DATA CACHE相当于一块小的内存,我们假设它为16K大,它会与一般物理内存交互。 
它和内存交互一般一次传输16个字节(32个字节),也就是: 


CACHE 字节0-15一次写到/读取物理内存 ,字节16-31一次写到/读取物理内存.32-47 ... ... 

这些一次被传输的字节被称为cache line。 
-------------------------------------------------------------- 

另外,cache写到物理内存的位置不是任意的, 
我们假定内存为64K,那么cache地址0的数值只能和物理内存的地址0, 16K, 32K交互;cache地址1的数值只能和物理内存的地址1, 16K+1, 32K+1交互 
。。。 。。。cache地址16K-1的数值只能和物理内存的地址6K-1, 16K+16K-1, 32K+16K -1交互 

这说明了两点: 

(1)假设对象A的一个字段长为16个字节,如果它放在物理地址 0-15,那么它将和cache的第一个cache line 交互,如果放在物理地址 8-23,那么 
如果CPU要访问这个字段,必须将第一个和第二个cache line 都读入,才能获得这个字段的信息,显然这样速度慢,所以一般字段需要cache line对齐, 
在这里就是16个字节对齐。 


(2)关于colour 


一般一个对象某些字段访问频繁些。 
假定一个cache(这个cache指slab的cache,不是上面提到CPU的L1 DATA CACHE)占用5个页面也就是20K. 
假定其中对象大小为32个字节,前16个字节访问频繁许多。 

假定对象A起始于物理地址0,对象C起始于31,对象B起始于物理地址16K,那么对象A,对象B的前16个字节都和第一个cache line 交互,后16个字节都和第二个cache line 交互 
对象C前16个字节与第3个cache交互。 

我们假定内核访问A后就访问B,再访问A,交错进行,并且前16个字节次数都是50次,后16个为10次。C也是。 

这样第一个cache line 要交互100次,第二个20次,一共120次。 

如果让对象B向后移动16个字节,也就是对象B的前16个字节与第二个cache line 交互,后16个与第3个交互。 
那么第一个为2次,因为只有开头结尾2次要与内存交互,其它每次都在L1 DATACACHE 中写就可以了。第2个cache line为20次左右(后面的只须在CACHE中读写),第3个cache line为20次, 
3个line一共才41次,你不妨仔细模拟一下。 

所以进行错位能降低CACHE的交互次数,从而提高CPU处理速度能力。 

这个错位(也就是上面的16个字节)就是colour.

### 替换最近使用的缓存行策略 在计算机体系结构中,缓存替换策略决定了当新数据需要存储到已满的缓存中应该移除哪一行。常见的几种缓存替换策略包括: #### 1. 随机替换 (Random Replacement) 随机选择一缓存行进行替换。这种方法简单易实现,但由于缺乏预测性和优化机制,在性能上通常不是最优的选择。 #### 2. 先进先出 (FIFO, First In First Out) 按照间顺序记录每进入缓存的数据项,并总是淘汰最早加入的那一项。尽管易于理解,但对于工作负载模式变化较大的情况表现不佳[^1]。 #### 3. 最近最少使用 (LRU, Least Recently Used) 跟踪各缓存行最后一次被访问的间戳或位置,优先淘汰最久未使用的那一行。此方法能较好地适应多种应用场景下的局部性原理,因此应用广泛。为了高效管理 LRU 列表,可以采用位图或其他紧凑的数据结构来表示相对次序关系。 ```c++ struct CacheLine { int tag; bool valid; // 是否有效标志 unsigned long timestamp; // 间戳用于模拟LRU行为 }; class LRUCache { private: std::unordered_map<int, CacheLine*> cacheMap; list<CacheLine> lruList; public: void access(int address) { auto it = cacheMap.find(address); if (it != cacheMap.end()) { // 命中 move_to_front(it->second); // 将其移到队列头部 } else { // 缺失 evict(); // 如果满了则驱逐最后面的一个元素 insert_new_line(address); // 插入新的缓存行至前端 } } void move_to_front(CacheLine* line){ lruList.splice(lruList.begin(), lruList, find(lruList.begin(),lruList.end(),line)); } void evict(){ if(cacheMap.size() >= MAX_SIZE){ CacheLine *last = &lruList.back(); cacheMap.erase(last->tag); lruList.pop_back(); } } void insert_new_line(int addr){ CacheLine newEntry{addr,true,time(NULL)}; lruList.push_front(newEntry); cacheMap[addr]=&lruList.front(); } }; ``` 对于使用了 Virtual Cache 的微架构而言,虽然 Bin-Index 算法仍然可能适用于某些场景,但主要是在更高级别的缓存(如 L2 或以上)而非追求极低命中延迟的一级缓存中找到更多应用实例。而针对具体某一层级内的 “最近使用过的” 行执行替换操作,则往往依赖上述提到的一种或组合形式的具体政策来进行决策。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值