并发,高并发,CPU多级缓存概念

最近一直在学习java并发编程。

整理笔记的过程也是对自己考核的过程。

一、并发与高并发概念

并发:同时有多个线程,【交替】被CPU执行。

高并发:保证系统能同时并行处理很多请求的【设计】。

可以看到,当谈论并发的时候,我们关注的是多个线程操作相同的资源时,如何保证线程安全,合理利用资源;而谈论高并发时,我们关注的是如果系统在短时间内遇到大量请求(比如淘宝双十一),那么我们如何提高系统的性能(包括硬件、网络、系统架构、开发语言等等)。

二、CPU多级缓存

(1)主存、高速缓存、CPU核心的关系


之所以需要缓存,是因为主存跟不上CPU频率,所以CPU常常等待主存,而cache就是缓解这种速度间的不匹配问题。

(2)CPU多级缓存之缓存一致性(MESI)

扫描二维码关注公众号,回复: 1934630 查看本文章

缓存一致性(MESI)是为了保证CPU多级缓存的共享一致性。

MESI定义了四种状态,也就是CPU对四种操作产生不一致的状态。缓存控制器监听到本地操作和远程操作的时候,需要对cache做出修改,从而保证数据在cache之间的一致性。


Mmodified被修改。该缓存行只被缓存在CPU的缓存中,并且是被修改过的,因此它与主存中的数据是不一致的,该缓存行的内存需要在某个时间点写回主存,这个时间点是允许其他CPU读取主内相应的内存之前。当这里的值被写回主存之后,该缓存行会变成E状态。

Eexclusive独享。该缓存行只被缓存在该CPU缓存中,是未被修改过的,与主存中数据一致的。这个状态可以在任何时刻,当有其他CPU读取该缓存行时,变成S状态。当CPU修改该缓存行内容时,该状态可以变成M状态。

Sshared共享。该缓存行可能被多个CPU缓存,并且各个缓存的数据和主存的数据一致,当有一个CPU修改该缓存行的时候,其他CPU从该缓存行是可以被作废的,变成I状态。

Iinvalid无效的。这个缓存是无效的,可能是其他CPU修改了该缓存。

四种操作:

Local read:读本地缓存中的数据

Local write:将数据写到本地的缓存中

Remote read:将内存的数据读取过来

Remote write:将数据写回到主存中

在一个有多核的系统中,每一个核都有自己的缓存来共享主存总线,每个CPU会发出读写请求,而缓存的目的是为了减少CPU读写共享主存的次数。

一个缓存除了在I状态之外都可以满足CPU的读请求。

一个写请求只有在ME状态下才能执行。如果处在S状态,必须先将该缓存中缓存行变成I状态。通常通过广播方式执行。不允许多个CPU修改同一个缓存行,即使修改该缓存行不同的数据也是不允许的。

一个处于M状态的缓存行,必须监听所有试图读缓存行的操作,这种操作必须在缓存将缓存行写回到主存,并将状态变回S状态之前被延迟执行。

一个处于S状态的缓存行,也必须监听其他缓存使改缓存行无效或者独享该缓存行的请求并将缓存行变成无效。

一个处于E状态的缓存行,要监听其他缓存读缓存中该缓存行的操作,一旦有该缓存行的操作,它就会变成S状态。

对于ME两种状态而言,数据总是精确的,和缓存行的真正状态是一致的,S状态可能是非一致的,如果一个缓存将处于S状态的缓存行作废,另一个缓存可能已经独享了该缓存行,但是该缓存却不会将缓存行升为E状态,因为其他缓存不会广播它们作废掉该缓存行的通知。由于缓存并没有保存该缓存行的copy数量,因此也没办法确定自己是否独享了该缓存行。

E更像一个投机性的优化,因为一个CPU想修改一个S状态的缓存行,总线事务需要将所有该缓存行copy的值变成I状态,但修改E状态的缓存,却不需要总线事务。

接下来,我们一起看一下CPU多级缓存的乱序执行优化。

(3)CPU多级缓存之乱序执行优化

它的意思就是说,CPU为了提高运算速度打乱了代码的执行顺序。

比如:


这里就有两种执行顺序:a.将a赋值为2,再将b赋值为3,最后计算a*b;b.将b赋值为3,再将a赋值为2,最后计算a*b,在单核单线程是没有问题,但是多核或者多线程就会出现问题。

比如我们在一个核上执行写入操作,然后在操作最后写一个标记来表示之前的数据已经准备好了,然后我们从另外一个核上通过判断这个标记,来判定需要的数据是否已经就绪。那如果考虑到上面说的乱序执行优化,这种做法就存在一定风险,比如标记先被写入,但是之前的操作并未完成,也就是这个值没有被写入。

这就是数据不安全,也就是我们后面要说的并发情况下,如何保证线程安全。



猜你喜欢

转载自blog.csdn.net/weixin_40459875/article/details/80289493