并发问题
物理计算机中的并发问题和JVM中的情况有很多相似之处,JVM的并发解决方案也很大的参考了物理机的实现。在计算机中,绝大多数的运算任务都不可能只靠处理器"计算"就能完成,处理器(CPU)至少要与内存(Memory)交互,如读取运算数据、存储运算结果等,这些I/O操作是很难消除的。也就是说,CPU要完成计算,就必须要和存储设备(Memory)打交道,然而内存与处理器的运算速度有几个数量级的差距。由于内存读写速度太慢,不能及时提供数据给CPU进行计算,会大大降低CPU的处理效率。为了解决CPU和内存(Memory)之间的速度匹配问题,现代计算机系统不得不加入一层读写速度尽可能接近CPU运算速度的高速缓存(Cache)来作为内存与CPU之间的缓冲:将运算需要使用到的数据复制到缓存(Cache)中,让运算能快速进行,当运算结束后再从缓存(Cache)同步回内存(Memory)之中,这样CPU就无须等待缓慢的内存读写了。
基于高速缓存的存储交互很好的解决了CPU与内存的速度矛盾,但也为计算机系统带来更高的复杂度,因为它引入了一个新的问题:缓存一致性(Cache Coherence)。在多处理器系统中,每个CPU都有自己的高速缓存,而它们又共享同一个主存(Main Memory)。当多个CPU的运算任务都涉及同一块主内存区域时,将可能导致各自的缓存数据不一致,如果真的发生这种情况,同步回到主存时以哪个CPU的缓存数据为准呢?为了解决一致性的问题,需要各个处理器访问缓存时都遵循一些协议,在读写时要根据协议来进行操作,这些协议有'MSI、MESI、MOSI、Synapse、Firefly'等。
除了增加高速缓存外,为了使得CPU内部的运算单元能尽量被充分利用,CPU可能会对输入代码进行乱序执行(Out-Of-Order-Execution)优化,CPU会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果是一致的,但并不保证程序中各个语句计算的先后顺序与输入代码中的顺序一致,因此,如果存在一个计算任务依赖另外一个计算任务的中间结果,那么其顺序性并不能靠代码的先后顺序来保证。
处理器、高速缓存、主内存交互关系

高速缓存的工作原理
CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就从内存中读取并送给CPU处理,同时把这个数据所在的数据块放入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。这样的读取机制使CPU读取缓存的命中率非常高,大多数CPU可达到90%左右。也就是说CPU下一次要读取的数据90%都在缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。
CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(未命中),这时CPU才访问内存。从理论上讲,在一颗拥有二级缓存的CPU中,读取一级缓存的命中率为80%。也就是说CPU一级缓存中找到的有用数据占数据总量的80%,剩下的20%从二级缓存中读取。有的CPU甚至会有三级缓存,这样做的目的是提高命中率,尽量减少直接从内存中读取数据。
如有不妥,请大家指出,大家一起探讨进步,灰常谢谢!
您的点赞和评论都是对我的鼓励,走过路过的,动动你们的手指吧!哈哈😄