并发编程语言爱好者Java

java并发编程(十五)CPU缓存结构是啥样的?

2021-12-30  本文已影响0人  我犟不过你

一、CPU缓存结构

现代CPU通常都是由三层缓存架构组成的,如下图所示:

CPU缓存结构.png

windows下的cpu:

windows

查看linux的cpu缓存如下:

[root@public-server9 ~]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    4
座:                 1
NUMA 节点:         1
厂商 ID:           GenuineIntel
CPU 系列:          6
型号:              79
型号名称:        Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
步进:              1
CPU MHz:             2399.998
BogoMIPS:            4799.99
超管理器厂商:  VMware
虚拟化类型:     完全
L1d 缓存:          32K
L1i 缓存:          32K
L2 缓存:           256K
L3 缓存:           35840K

二、缓存行(Cache LIne)

相信大家应该都听过缓存行,作为CPU缓存中的最小缓存单元,通常是大小是64字节。

我们可以使用如下的方式查看linux下的缓存行大小:

[root@public-server9 ~]#  cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size
64

CPU当中数据的移动不是以一个字节为单位,而是以一个缓存行为单位的。

当 CPU 把内存的数据载入缓存时,会把临近的64Byte的数据一同放入同一个Cache line中。

根据空间局部性原理:临近的数据在将来被访问的可能性大。

三、CPU缓存一致性

多个cpu对同一块内存同时读写,会引起冲突问题,这一问题就是CPU的缓存一致性问题。

如何保证多级缓存中的数据一致性呢?

MESI协议 是基于Invalidate的高速缓存一致性协议,并且是支持回写高速缓存的最常用协议之一。MESI协议要求在缓存不命中且数据块在另一个缓存时,允许缓存到缓存的数据复制。这样一来减少了主存的事务操作,极大提高了性能。

MESI中每个缓存行都有四个状态,分别是:

下面简要描述一下状态转换的流程和关系:

1)M、E、S状态下的缓存行,都可以满足CPU的读请求;I状态是无效的,会重新去获取。

2)E状态下的缓存行,当发生写请求时,会将状态转换成M,但此时并不向主存同步。E状态下的缓存行要监听读请求,当有读请求时,需要将状态变为S。

3)M状态下的缓存行,需要监听其读操作,如果发生读操作,会将其他缓存当中的该缓存行(S状态),变成I状态,并且将自己写入主存,然后变成S状态。

4)S状态的缓存行,如果发生写请求,会将自己变成M状态,如果有读请求,则会重复3)中的步骤,将其他缓存中的缓存行变成I状态,将自己写入主存,变成S状态。

5)S状态下的缓存行,需要监听该缓存行的失效操作,如果发生失效操作,需要将自身变成I状态。

6)I状态的缓存行发生读请求,需要从主存获取。

上面就形成了一个闭环。

本文主要对CPU的缓存一致性做一个入门了解,便于多线程并发编程的学习,过多的本文将不讲解了。

四、内存屏障

下面简单了解一下什么是内存屏障。

前面的文章当中,我们曾提到过线程间的可见性,以及有序性,那么是如何实现的呢?当时我们说是使用volatile关键字,其底层的本质就是通过内存屏障。

内存屏障主要分为读屏障写屏障


本篇简单了解原理,下一章节我们会学习volatile的原理。

上一篇 下一篇

猜你喜欢

热点阅读