https://zhuanlan.zhihu.com/p/31422201
Cache在哪里呢
现代多核CPU L1、L2在核中,L1分L1data和L1code,L3L4是多核共享
什么是Cache
Memory也被称为Cache,是存储子系统的组成部分,存放程序经常使用的指令和数据
Cache是快设备为了缓解访问慢设备延时预留的 Buffer,从而在掩盖访问延时的同时,尽可能提高数据传输率。快和慢是一个相对概念,与微架构(Micro Architecture)中的L1L2L3相比,DDR就是慢设备;在磁盘IO系统中,DDR却是快速设备
Cache的访问速度
- 时钟周期,小于1ns
- L1,1-3ns
- L2,3-12ns
- L3,12-38ns
- DRAM,65ns+
Cache是怎么组织和工作的
2-ways,4-ways cache,它是什么意思呢
Cache的组成和访问方式
在现代大多数处理器中,Cache被分为很多行(Cache Line),Cache Line大小不一,从16Byte到128Byte不等,一般大小是64个Byte,我们在这之后都认为Cache Line有64B组成。我们假设有512KB的Cache,就可以划分成8192个Cache Line
虚拟地址变换成物理地址的简单过程
虚拟地址 = 选择符 + 偏移值
虚拟地址通过分段机制生成线性地址
线性地址通过分页机制生成物理地址,其中需要页表,页表由操作系统维护放在内存中
页表
一次内存操作需要数百个时钟周期,如果每次地址转换都要查看内存页表也太浪费时间了。现代计算机为了加速这个过程,使用了TLB,TLB可以看做页表的Cache,CPU每次转换地址都会查看TLB,如果有了就不用寻找内存页表了。
TLB是Cache命中的基本条件。TLB不命中,会更新TLB项,这个代价非常大,Cache命中的好处就基本没有了。在TLB命中的情况下,物理地址才能够被筛选,Cache命中与否才能够达成。
映射方法
直接映射 Direct Mapping
每个地址都可以立刻直接且只能映射到某个Cache Line上。
假设我们有1GB物理内存,我们把它们分成8192份,每份就是128KB。
判断Cache算法命中方法就是直接映射直接地址/128
缺点就是Cache Miss高,数据相关性
全相联映射 Fully Associative Mapping
全映射就是所有Cache Line可以对应说有地址。这样Cache就不会造成冷热不均,Cache Miss减小了很多,但是一条不命中的寻找,要遍历整个Cache
n路组相联映射 n-ways Set-Associative mapping
将Cache分成n个组(set),每一组对应一个地址。也就是说一个地址可以映射到n个Cache Line中
这个n=1,就是直接映射;n=cache大小,就是全相关映射,那么n应该取几呢
一般都是2的n次幂,Cache越接近内存,映射系数越大
缓存着色 Cache Coloring
Inclusive Cache或者Exclusive Cache 上一层Cache的数据在下一层中是否包含
Cache为什么有那么多级?为什么一级比一级大?是不是Cache越大越好
为什么Cache分这么多级,而是不是直接把L1或者L2增大了事?我们为什么不能直接做出个Cache奇大的CPU呢
为什么Cache要分级
首先我们要知道L1和L2 Cache的区别,虽然它们都是由CAM(Content Addressable Memory )为主体的tag和SRAM组成的
L1(先不考虑指令和数据L1的不同)是为了更快的速度访问而优化过的,它用了更多/更复杂/更大的晶体管
L2相对来说是为提供更大的容量优化的,用了更少/更简单的晶体管,同样的道理还可以推广到L2和L3上
单位面积内能放入的晶体管数量是一定的,如果都给L1,容量太少,Cache命中率低,功耗太高。都给L2,容量大了但是延迟高了
Cache为什么不会做的很大
一个SRAM六个晶体管,加上tag需要更多
为简化起见,我们假设L1维持在不到60%的命中率(实际情况95%左右)。从图中可以看出,随着L2容量的增加,开始时L2和整体命中率快速提高,这表明提高L2容量效用很明显。随后L2的命中率在容量增加到64KB后增长趋缓,而整体命中率也同时趋缓,最后甚至基本不大变化了。增加同样的晶体管,而受益却越来越少,出现了边际效用递减的问题。
制程进化得来的多余晶体管,增大Cache不如多做一级Cache
同时我们需要能够在一个时钟频率内访问一遍L1,所以L1也不能太大
缓存一致性
什么是Cache一致性
在一个多处理器系统中,Cache们和内存池可能对同一份数据有多份副本,如何保证这些副本的一致性(Coherency)是个必须严肃对待的问题
Cache一致性模型 MESI protocol
四个状态:
- modified M
- Exclusive E
- Shared S
- Invalid I
SE 经过其他缓存写到 I
读未命中到 S
写未命中到 E
M 读写之后到 M
SE 读之后到自己
S 写之后到 E
E 写之后到 M
M 其他读写之后到 S
S 其他写之后到 I
显存为什么不能当内存使?
因为PCIe和其他所有的设备一样,他们的memory不能被CPU cache。那么为什么不能被Cache呢?因为无法保证Cache一致性。
latency number 每个程序员都应该知道的延迟时间
1ms = 1,000us = 1,000,000ns
Latency | 延迟 | ns | us | ms | 备注 |
---|---|---|---|---|---|
L1 cache reference | L1缓存访问 | 0.5ns | |||
Branch mispredict | 转移、分支预测 | 5ns | |||
L2 cache reference | L2缓存访问 | 7ns | 14x L1 cache | ||
Mutex lock/unlock | 互斥锁\解锁 | 25ns | |||
Main memory reference | 主存访问(L3、L4) | 100ns | 20x L2 cache, 200x L1 cache | ||
Compress 1K bytes with Zippy | 1k字节压缩(Zippy) | 3,000ns | 3us | ||
Send 1K bytes over 1 Gbps network | 在1Gps传输速度网络传输1K数据 | 10,000ns | 10us | ||
Read 4K randomly from SSD* | SSD随机读4K数据 | 150,000ns | 15us | ~1GB/sec SSD | |
Read 1 MB sequentially from memory | 内存顺序读取1MB | 250,000ns | 25us | ||
Round trip within same datacenter | 数据中心轮询 | 500,000ns | 50us | ||
Read 1 MB sequentially from SSD* | 内存顺序读取1MB | 1,000,000 ns | 1,000us | 1ms | ~1GB/sec SSD, 4X memory |
Disk seek | 磁盘搜索 | 10,000,000ns | 10,000us | 10ms | 20x datacenter roundtrip |
Read 1 MB sequentially from disk | 机械磁盘里面读出1MB | 20,000,000ns | 20,000us | 20ms | 80x memory, 20X SSD |
Send packet CA->Netherlands->CA | 数据包从加拿大到荷兰再到加拿大的延迟 | 150,000,000ns | 150,000us | 150ms |