并发与高并发专题--并发编程操作系统基础

一、CPU多级缓存


1.1 简单介绍CPU参数

当前笔者所用的笔记本CPU是8代i7-8750H(6核12线程、频率2.2GHz/睿频4.1GHz、三级缓存9MB)。
主频,可以理解为处理速度,相当于手臂肌肉,主频越高,力量越大。睿频是临时的超频。
核心,相当于手臂,6核即六条手臂。
线程,相当于手,6核12线程相当于每个手臂长两只手,提高干活效率,压榨单一CPU核心的处理能力。


1.2 CPU 缓存的必要性

最早的CPU是与主存直接数据交互,CPU将主存的数据取出送到寄存器中,计算完毕后写回主存。但随着CPU的快速发展,内存数据的I/O速度远远不及CPU的处理速度,这就导致CPU等待,浪费资源。

高速缓存的出现是为了缓解CPU与内存之间速度不匹配的问题。此时CPU数据的存取都要经过高速缓存。将运算所需的数据复制到缓存中,让运算快速进行,运算结束后再从缓存同步回内存。


1.3 局部性原理

计算机的存储系统采用分级存储体系的理论依据是程序访问的局部性原理。CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。
(1)时间局部性:如果某个数据被访问,那么在不久的将来它很可能再次被访问,例如循环、堆栈(包括递归)。
(2)空间局部性:如果某个数据被访问,那么与它相邻的数据很快也可能被访问,例如数组。

 int sum = 0;
 for(int i = 0; i < M; i++) {
     for(int j = 0; j < N; j++) {
         sum += a[i][j];
     }
 }

如上双重嵌套循按行顺序读数组元素,具有良好的空间局部性。同时步长越小,空间局部性越好。如果交换i和j的循环,按照列扫描数组,空间局部性很差。
【注】由于循环体被执行多次,故代码也具有很好的时间局部性。

二、存储器结构


2.1 存储层次结构


层次结构的思想是,上一层是下一层的缓存,即下一层数据的子集。
缓存命中:当程序要访问k+1层的某个数据对象d时,会先在k层的块中查找d。如果d刚好缓存在k层,即缓存命中,直接从k层读取d。
缓存不命中:如果k层中没有缓存数据对象,即缓存不命中。第k层缓存会取出k+1层中d所在的那个块。如果缓存满了,则进行替换。

如图为CPU高速缓存,一级缓存主要是缓存数据和缓存指令。一二级缓存为核心独享,三级缓存为核心共享。
速度:cpu寄存器 >> cache >> memory


2.2 高速缓存组织结构

假设存储器(以主存为例)地址有m位,那么内存地址可以达到2^m个。高速缓存(以L1缓存为例)会将m个地址位划分为三个字段,t个标记位、s个组索引位和b个块偏移位和。

高速缓存被分为S = 2^s个高速缓存组的数组,每个缓存组包含E个高速缓存行。缓存行包含了B = 2^b字节的数据块,1个有效位用于标记行是否包含有意义信息,t个标记位。t个标记位即当前块的内存地址的t个标记位,唯一标识块。


当CPU从主存地址A中读一个字时,CPU首先会把地址A发送给高速缓存(假设为L1)。
(1)首先会根据地址A的s个组索引位找到缓存组。
(2)找到组后,再根据地址A的t个标记位找到缓存行(只有在设置了有效位,并且缓存行标记位与地址A标记位匹配时,才表示缓存行包含这个字)。
(3)找到行后,根据地址A的b个块偏移位找到数据块中的字。

三、缓存一致性


3.1 缓存一致性(Cache Coherence)问题

基于高速缓存的存储交换模型很好地解决了内存与CPU的速度矛盾,也引入了缓存一致性问题。
每个核心都有自己的高速缓存,同时共享着同一主内存,当涉及到同一块主内存区域的运算任务时,就可能导致各自缓存数据不一致的问题。因此,需要各核心访问缓存时遵循缓存一致性协议,例如intel MESI协议。


3.2 MESI协议

核心思想:
如果变量是共享变量,在CPU写数据时会发信号给其他核心,使得其他核心该数据的缓存为失效状态。当其他核心想要使用该数据时,由于缓存不命中,将从主存中重新读取。
四种状态:M/E/S/I
E(Exclusive):缓存行有效,数据和主存数据一致,数据只存在本Cache中。
例:只有Core0变量x。
S(Shared):缓存行有效,数据和主存数据一致,数据存在于多个Cache中。
例:多个Core访问变量x。
M(Modified):缓存行有效,数据已经被修改,与主存数据不一致,只存在本Cache中。
I(Invalid):缓存行无效。
例:多个Core访问变量x,各缓存行都是S状态。当Core0修改了变量x的值,该缓存行变为M状态,其他Core变量x所在缓存行变为I状态。

状态切换

例如其他Core读取主存数据后,当前Core该数据所在的缓存行如果是E状态,则变为S状态。
四种触发操作分别为:
Local Read:本地读取数据。
Local Write:本地写入数据。
Remote Read:远端读取数据。
Remote Write:远端写入数据。

此处对MESI的介绍是很浅显的,有兴趣的同学可以参考其他资料。

四、乱序执行优化

处理器为了提高运算速度,可能会对输入代码进行乱序执行优化,在计算之后将乱序执行的结果重组。保证结果与顺序执行结果一致,但不保证程序语句执行顺序与代码顺序一致。类似JVM的指令重排序。

参考资料

《深入理解计算机系统》(原书第三版)

发布了17 篇原创文章 · 获赞 41 · 访问量 9996

猜你喜欢

转载自blog.csdn.net/awecoder/article/details/95906780
今日推荐