现代计算机理论模型,工作原理,以及硬件是如何实现并发安全
1.冯·诺依曼体系
现代计算机的模型都是基于冯·诺依曼体系的,冯·诺依曼体系的基本组成有存储器,计数器,控制器,输入和输出设备,总共有这五大本分组成。下图是我基于这五大组成部分画了一个组成图来表示他们之间的关系,如图1-1。
图1-1
基于冯·诺依曼体系,首先控制器从内存中取出指令,有控制器来执行,控制器通过计数器来完成各种逻辑运算,算术运算等,然后将数据写会内存,输入设备输出设备更是常见,在这里就不一一赘述,重点是下面的内容。
2.计算机的硬件结构
计算机的硬件结构更是基于冯·诺依曼体系的,主板上主要由cpu,内存,总线等重要部件组成,其大致的示意图如下图2-1所示:
图2-1
cpu是主板上的核心部件,主要负责指令的执行,内存通过内存总线和I/O桥相连,在这里I/O桥可最大程度的解决cpu与内存速度不匹配的问题,一般cpu的速度是gHZ为单位的,而内存条则是几百兆HZ为单位,两者存在速度不匹配的问题,在这里I/O桥可以缓解两者速度不匹配,还有一个也能缓解cpu与内存的速度不匹配的问题,那就是cpu缓存,她的速度很快,但是成本相对较高,不适合内存条大量使用,因此apu缓存很小,但它可有效的缓解此问题。
总线是cpu与其他部件交互的通道,可通过USB控制器链接鼠标,键盘等,图形适配器可链接显示器等。
3.多cpu缓存架构
多cpu在与内存交互的时候,是存在并发安全的问题的,当一个主板上有多个cpu时,和cpu多核又是不一样的,在这里就来讲讲多cpu时,cpu是怎么从内存读取数据,并保证他们的并发安全,这里完全是从硬件层次来讲,这对后面去学习并发,线程和JMM,以及JVM有很大的帮助,有些软件层次的技术实现,完全是基于现有的硬件基础。
多cpu的情况下,当其中一个cpu从内存读取数据,放入cpu缓存,如果该cpu对这个数据要进行修改,这个时候,另一个cpu刚好也从内存读取了该数据,也要对他进行修改,那么当两个cpu同事从该内存中读取该数据,并对他进行逻辑,算术等运算是,这个时候内存中在接受cpu返回的该数据是不准确的,就存在了并发的安全问题(技术在不断发展,cpu从以前的单核,一些cpu厂家有段时间一致于追求提高cpu的运算频率,到后来发现cpu的频率提高达到了瓶颈,要想在提高cpu的运算速度,光靠提高频率是远远不够的,这个时候,一些技术大牛们就想到了单个cpu多核,这样就立竿见影的提高了cpu的速度)。这个时候就有了总线锁和后来的缓存一致性协议来实现并发安全。下图是我多cpu与内存交互的一个简图,见下图3-1。
图3-1
先讲讲总线锁,总线锁很简单,早期奔腾cpu只能依靠总线锁来解决并发的问题,当一个cpu读取了内存中的某个数据的时候,该cpu对总线加了把锁:lock。当其他cpu通过总线去访问内存的该数据时是访问不了的,这就是总线锁。总线所有很多缺点,比如cpu的利用率低,当多个cpu同时对一个数据访问时,只能有一个cpu能拿到这把总线锁,其他cpu只能处于低效率状态。总线锁在早期的奔腾系列的cpu用的很多,到了后来的酷睿以及新的一些cpu绝大部分使用缓存一致性协议,下面我就来详细说明一下MESI缓存一致性协议,当cpu从主存中读取了该数据进入cpu的缓存行(catch line)中的时候,并且其他cpu没有读取该数据,该缓存行的状态为E状态(Exclusive),也就是独享状态,这个时候如果该对该缓存行进行了修改,那么该缓存行的状态就会变成M状态(Modified),也就是修改状态,表示该缓存行的数据修改了,与内存中的数据不一致,当该cpu监听到其他cpu也要读取该数据的时候,那么,该缓存行的状态会变成S状态(Shared),也就是共享状态,cpu会在一个特定的时间节点将数据协会内存(下篇博文中讲到两个线程读取内存一个变量的时候,会用到这个知识点),保证缓存行的数据与内存一致,从而其他cpu也可以读取该数据。其中该缓存行在S状态的时候,也会去监听其他缓存行的消息,当其他缓存行变成M状态的时候,此时该缓存行就会变成I状态(Invalid),也就是无效状态,当有条件触发需要该数据的时候,会重新从内存中读取该数据。MESI缓存一致性协议依赖于总线的嗅探机制,该机制时刻监听cpu中缓存行的状态,并通过总线发消息来将缓存航状态发送给其他缓存行。
在这里需要注意的是,现代的酷睿系列处理器虽然用的很多MESI缓存一致性协议,保证了cpu的利用率,但是他也有使用的限制,也就是缓存行,当该数据的长度超过了该缓存航的最大容量,那么他只能使用总线锁来保证并发的安全。