cpu cache line 原理:blog.csdn.net/zdl1016/article/details/8882092
关于CPU Cache:cenalulu.github.io/linux/all-about-cpu-cache/
CPU和内存的那些事:www.tuicool.com/articles/mUR3Er
关于cpu的cache:blog.csdn.net/gogdizzy/article/details/9384153
1、cpu的结构
cpu主要包括registers,load/store buffers,L1 cache,L2 cache和多core共享的 L3 cache。
2、各级存储的性能
3、cache分类
按功能划分,缓存可以分为指令缓存(code cache或instruction cache指令缓存)、数据缓存(data cache)、TLB缓存(translation lookaside buffer,加速虚拟地址转物理地址)。按速度划分,当前主流CPU都有二级甚至三级缓存(分别称之为L1,L2,L3)。大部分CPU都把指令缓存和数据缓存分开,以提高性能;也有合并到一起的,降低硬件开销。一般只把数据缓存分级别。
4、cache相关概念
cache line:每次内存和CPU缓存之间交换数据都是固定大小,cache line就表示这个固定的长度。
cache set:一个或多个cache line组成cache set,也叫cache row。
cache entry:缓存条目,包含cache line内容(value)和对应的地址(key),可以看做是哈希表中的一项。
cache hit:缓存命中,查找的地址在cache中。
cache miss:缓存未命中,查找的地址不在cache中。
hit rate:命中率,cache hit /(cache hit + cache miss)。
5、cache entry
cache由若干个cache entry组成(个人理解),cache entry由以下三部分组成。
tag:包含部分内存地址
data block:就是一个cache line的内容
flag bits:一般包含数据是否有效(valid bit)和数据是否被写(dirty bit),指令缓存因为只读,只需要valid bit,但是不知道具体实现是怎样的。
6、N-way associative
内存数据到cache line的映射策略主要有fully associative,Direct Mapped Cache,N-way associative,N-way associative是fully associative和Direct Mapped Cache的折中。N-way associative将cache划分成2维矩阵,每一行包含N个cache entry,它们对应的内存地址的后几位都是相同的,可以把cache line想象成hashmap,每一个hash link有N个cache line,这N个cache line组成一个cache set。
7、内存地址到cache的映射
一个有效内存地址可以分为
tag:与cache entry中的tag相同
index:表示装入cache set的索引号,对应N-way associative的一个cache set(cache row)。
block offset:表示这个地址在数据块(data block)中的偏移量
举例来说:
对于32位地址总线的系统,如果L1 cache大小为8k(个人理解只算了cache line的大小),每个cache line是64 bytes,4个cache line组成一个cache set。那么总共就有8k / 64 bytes = 128个cache line,每4个组成一组,那就有128 / 4 = 32个cache set,所以block offset占6个bit(2^6=64),index占5个bit(2^5=32),tag占21个bit(32 - 5 - 6)。
那么映射过程(1)根据内存地址中间的5bit计算出index,找到对应的cache set(2)根据最前面的21bit计算出tag,然后遍历cache set找到对应的cache line(3)根据内存地址最后的6bit计算出数据在cache line中的offset,按照数据长度读取cache中的数据。
8、cpu读内存与cache淘汰策略
cpu从来都不直接访问内存, 都是通过cache间接访问内存,每次访问内存时先查看cache中是否有对应地址的数据,如果cache中没有则先分配一个cache entry,然后再把内存中的数据copy到刚刚分配的cache entry的cache line中,再从cache line中读取数据。
cache中包含的cache entry的数目是有限的,并且远小于内存,当cache entry全部都被占用的时候,就需要一个淘汰策略将部分cache entry淘汰掉,一般使用LRU策略。
9、cpu写内存与数据一致性问题
cache中的数据更新后,需要回写到内存,考虑性能和数据一致性,主要有3种回写策略(1)每次更新都回写,也叫write-through cache(2)更新后不回写,标记为dirty,仅当cache entry被evict时才回写(3)更新后,把cache entry送如回写队列,待队列收集到多个entry时批量回写。
有两种情况可能导致cache中的数据过期(1)DMA,有其他设备直接更新内存的数据(2)SMP,同一个cache line存在多个CPU各自的cache中,其中一个CPU对其进行了更新。数据同步一般使用MESI协议和MOESI协议。
10、超线程技术
当发生cache miss时(特别是read cache miss,在cpu运行命令时,read只能是同步的,write可以是异步的),cpu在等待数据从内存读进cache期间,没事可做,CPU在硬件层面,把一个CPU模拟成两个CPU,在上层看来是两个CPU,并发的执行两个线程.,这样当一个线程因cache miss在等待时,另一个线程可以执行。
在64位数据总线的系统中,只有操作的数据小于64bit并且在内存中是64bit对齐且cache在同一个cache line中才能保证是原子操作,如果cache line大于等于64bit并且是64bit的整数倍,那么基本可以认为在内存中是64bit对齐的数据也会保存在同一个cache line中,可以认为是原子的。
在编码中尽量利用cache,减少直接访问内存,减少多个共享变量在同一个cache line中,降低False Sharing现象。