CPU缓存
多级缓存:
- L1 级(一级缓存)是CPU第一层高速缓存,分为数据缓存和指令缓存。一般服务器CPU的L1缓存的容量通常在32-4096KB。
- L2 级的存在是突破L1级高速缓存容量的限制,再次提高CPU的运算速度。
- L3 级现在的都是内置的。其实际作用是,L3缓存的应用可以进一步降低内存延迟,同时提升大数据量计算时处理器的性能。具有较大L3缓存的处理器提供更有效的文件系统缓存行为及较短消息和处理器队列长度。一般是多核共享一个L3缓存。
CPU在读取数据时,先在L1中寻找,再从L2寻找,再从L3寻找,然后是内存,再后是外存储器。
缓存同步协议——MESI协议
- 修改态(Modified) — 此cache行已被修改过(脏行),内容已不同于主存,为此cache专有;
- 专有态(Exclusive) — 此cache行内容同于主存,但不出现于其它cache中;
- 共享态(Shared) — 此cache行内容同于主存,但也出现于其它cache中;
- 无效态(Invalid) — 此cache行内容无效(空行)。
高速缓存确实提供了便利,但也会存在这样一个问题:在同一个时间点,各CPU多看到同一内存地址的数据可能是不一致的。
CPU性能优化——指令重排序
当CPU写缓存时发现缓存区块正被其他CPU占用,为了提高CPU处理性能,可能将后面的读缓存命令优先执行。重排不是随意的,需要遵循as-if-serial语义,即不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。换句话讲:编译器和处理器不会对存在数据依赖关系的操作做重排序(以下方图例说明)。但是这个指令重排序的优化存在一个问题,它仅在单CPU自己执行的情况下能保证运行结果的正确性,在多核多线程中,指令逻辑无法分辨因果关系,可能出现乱排序导致得到错误结果的情况
内存屏障
为了解决CPU缓存优化所带来的问题,处理器提供了两个内存屏障:
- 写内存屏障:在指令后插入Store Barrier,能让写入缓存中的最新数据更新写入主内存,让其他线程可见。强制写入主内存,这种显示调用,CPU就不会因为性能考虑而去对指令重排。
- 读内存屏障:在指令前插入Load Barrier,可以让高速缓存中的数据失效,强制从主内存加载数据。强制读取主内存内容,让CPU缓存与主内存保持一致,避免了缓存导致的一致性问题。