cpu cache line学习

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 cache line学习_第1张图片


cpu cache line学习_第2张图片

cpu主要包括registers,load/store buffers,L1 cache,L2 cache和多core共享的 L3 cache。

2、各级存储的性能

cpu cache line学习_第3张图片

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现象。

你可能感兴趣的:(cpu cache line学习)