1、多线程同步——CPU、core核、线程、内存
CPU 的运行原理
控制单元在时序脉冲的作用下,将指令计数器里所指向的指令地址(这个地址是在内存里的)送到地址总线上去,然后 CPU 将这个地址里的指令读到指令寄存器进行译码。对于执行指令过程中所需要用到的数据,会将数据地址也送到地址总线,然后 CPU 把数据读到 CPU 的内部存储单元(就是内部寄存器)暂存起来,最后命令运算单元对数据进行处理加工。周而复始,一直这样执行下去。
CPU的缓存
CPU缓存通常分成了三个级别:L1
,L2
,L3
。级别越小越接近 CPU,所以速度也更快,同时也代表着容量越小。
L1 是最接近 CPU 的, 它容量最小(例如:32K
),速度最快。每个核上都有一个 L1 缓存,每个核上其实有两个 L1 缓存, 一个用于存数据的 L1 d-Cache(Data Cache),一个用于存指令的 L1 i-Cache(Instruction Cache)。
L2 缓存 更大一些(例如:256K
),速度要慢一些, 一般情况下每个核上都有一个独立的 L2 缓存。
L3 缓存是三级缓存中最大的一级(例如:3MB),同时也是最慢的一级, 在同一个 CPU 插槽之间的核共享一个 L3 缓存。
读取数据过程。就像数据库缓存一样,首先在最快的缓存中找数据,如果缓存没有命中(Cache miss) 则往下一级找, 直到三级缓存都找不到时,向内存要数据。一次次地未命中,代表取数据消耗的时间越长。
计算过程。程序以及数据被加载到主内存;指令和数据被加载到 CPU 的高速缓;CPU 执行指令,把结果写到高速缓存;高速缓存中的数据写回主内存。
【参考】
Core核
一个核心只能同时执行一个线程
线程切换
- cpu给线程分配时间片(也就是分配给线程的时间),执行完时间片后会切换都另一个线程。
- 切换之前会保存线程的状态,下次时间片再给这个线程时才能知道当前状态。
- 从保存线程A的状态再到切换到线程B时,重新加载线程B的状态的这个过程就叫上下文切换。
- 而上下切换时会消耗大量的cpu时间。
【参考】
认识cpu、核与线程 - jiajun_geek - 博客园 (cnblogs.com)
关于线程上下文切换,你知道多少? (qq.com) 有协程内容
重排序与内存可见性
CPU中每个核在执行线程时,都会创建一个本地缓存来保存主内存中的数据。在修改后,再异步写会给主内存。多个线程间对于变量的交互,是通过主内存来进行的。那么这个过程中,就存在一个多个线程间本地缓存同步的问题。比如说,现在对于一个主内存中的变量x=3,线程A将该值修改为x=4,但是,在线程A将数据同步到主内存前,线程B中就读取了数据。那么线程B中就讲讲本该x=4的值读成了x=3,造成了线程间同步的错误。
【参考】
内存一致性,指令重排序,内存屏障,volatile解析_volatile内存屏障证明-CSDN博客