1)控制器(Control):是整个计算机的中枢神经,是对程序规定的控制信息进行解释,根据其要求进行控制,调度程序、数据、地址,协调计算机各部分工作及内存与外设的访问等。
2)运算器(Datapath):运算器主要是对数据进行各种算术运算和逻辑运算,也就是对数据进行加工处理。
3)存储器(Memory):主要存储程序、数据和各种信号、命令等信息,并在需要时提供这些信息。
4)输入(Input system):输入设备是计算机的重要组成部分,输入设备与输出设备合称为外部设备,简称外设,输入设备的作用是将程序、原始数据、文字、字符、控制命令或现场采集的数据等信息输入到计算机。常见的输入设备有键盘、鼠标器、磁盘机、光盘机等。
5)输出(Output system):输出设备与输入设备同样是计算机的重要组成部分,它把计算机的中间结果或最后结果、机内的各种数据符号及文字或各种控制信号等信息输出出来。常用的输出设备有显示终端CRT、打印机、激光印字机、磁带、光盘机等。
现代计算机模型是基于 冯诺依曼计算机模型
上图是一个理论的抽象简化模型,下图就是具体的应用,也就是现代计算机中的硬件结构
最核心的部分就是:CPU、内存
控制单元是整个CPU的指挥控制中心,由指令寄存器IR(Instruction Register)、指令译码器ID(Instruction Decoder)和 操作控制器OC(Operation Controller) 组成,对协调整个电脑有序工作极为重要。它根据用户预先编好的程序,依次从存储器中取出各条指令,放在指令寄存器IR中,通过指令译码(分析)确定应该进行什么操作,然后通过操作控制器OC,按确定的时序,向相应的部件发出微操作控制信号。
操作控制器OC中主要包括:节拍脉冲发生器、控制矩阵、时钟脉冲发生器、复位电路和启停电路等控制逻辑。
运算单元是运算器的核心。可以执行算术运算(加减乘数基本运算及其附加运算)和逻辑运算(包括移位、逻辑测试或两个值比较)。相对控制单元而言,运算器接受控制单元的命令而进行动作,即运算单元所进行的全部操作都是由控制单元发出的控制信号来指挥的,所以它是执行部件。
存储单元包括 CPU 片内缓存Cache和寄存器组,是 CPU 中暂时存放数据的地方,里面保存着那些等待处理的数据,或已经处理过的数据,CPU 访问寄存器所用的时间要比访问内存的时间短。 寄存器是CPU内部的元件,寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快。采用寄存器,可以减少 CPU 访问内存的次数,从而提高了 CPU 的工作速度。寄存器组可分为专用寄存器和通用寄存器。专用寄存器的作用是固定的,分别寄存相应的数据;而通用寄存器用途广泛并可由程序员规定其用途。
CPU为了提升执行效率,减少CPU与内存的交互(交互影响CPU效率),一般在CPU上集成了多级缓存架构,常见的为三级缓存结构:
L1 Cache:分为数据缓存和指令缓存,逻辑核独占
L2 Cache:物理核独占,逻辑核共享
L3 Cache:所有物理核共享
存储器存储空间大小:内存>L3>L2>L1>寄存器;
存储器速度快慢排序:寄存器>L1>L2>L3>内存;
缓存是由最小的存储区块-缓存行(cacheline)组成,缓存行大小通常为64byte
缓存行(L1缓存大小是512kb,而cacheline = 64byte,那L1里有512 * 1024/64个cacheline)
CPU读取存储器数据步骤
1)CPU要取寄存器 A 的值,只需要一步:直接读取。
2)CPU要取L1 cache的某个值,需要1-3步(或者更多):把cache行锁住,把某个数据拿来,解锁,如果没锁住就慢了。
3)CPU要取L2 cache的某个值,先要到L1 cache里取,L1当中不存在,在L2里,L2开始加锁,加锁以后,把L2里的数据复制到L1,再执行读L1的过程,上面的3步,再解锁。
4)CPU取L3 cache的也是一样,只不过先由L3复制到L2,从L2复制到L1,从L1到CPU。
5)CPU取内存则最复杂:通知内存控制器占用总线带宽,通知内存加锁,发起内存读请求,等待回应,回应数据保存到L3(如果没有就到L2),然后L3/2到L1,L1到CPU,之后解除总线锁定。
CPU在摩尔定律的指导下以每18个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及CPU。这就造成了高性能的内存和硬盘价格及其昂贵。然而CPU的高度运算需要高速的数据。为了解决这个问题,CPU厂商在CPU中内置了少量的高速缓存以解决I/O速度和CPU运算速度之间的不匹配问题。
在CPU访问存储设备时,无论是存取数据或存取指令,都趋于聚集在一片连续的区域中,这就被称为局部性原理。
时间局部性(Temporal Locality):如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。比如循环、递归、方法的反复调用等。
空间局部性(Spatial Locality):如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。比如顺序执行的代码、连续创建的两个对象、数组等。
带有高速缓存CPU执行计算的过程
1)程序以及数据被加载到主内存
2)指令和数据被加载到CPU的高速缓存
3)CPU执行指令,把结果写到高速缓存
4)高速缓存中的数据写回主内存
CPU有4个运行级别,分别为:ring0、ring1、ring2、ring3
Linux与Windows只用到了:ring0、ring3
操作系统内部程序指令通常运行在 ring0 级别,操作系统以外的第三方程序运行在ring3级别,第三方程序如果要调用操作系统内部函数功能,由于运行安全级别不够,必须切换CPU运行状态,从ring3切换到ring0,然后执行系统函数。
JVM创建线程,线程阻塞唤醒是重型操作了,因为CPU要切换运行状态。
操作系统有用户空间与内核空间两个概念,目的也是为了做到程序运行安全隔离与稳定。
那么这两个空间也对应了不同的线程模型
内核线程模型(KLT)对应内核空间:系统内核管理线程(KLT),内核保存线程的状态和上下文信息,线程阻塞不会引起进程阻塞。在多处理器系统上,多线程在多处理器上并行运行。线程的创建、调度和管理由内核完成,效率比ULT要慢,比进程操作快。
用户线程模型(ULT)对应用户空间:用户程序实现,不依赖操作系统核心,应用提供创建、同步、调度和管理线程的函数来控制用户线程。不需要用户态/内核态切换,速度快。内核对ULT无感知,线程阻塞则进程阻塞。
虚拟机指令集架构主要分两种:
1)栈指令集架构
2)寄存器指令集架构
关于指令集架构的wiki详细说明:
1)设计和实现更简单,适用于资源受限的系统。
2)避开了寄存器的分配难题:使用零地址指令方式分配。
3)指令流中的指令大部分是零地址指令,其执行过程依赖与操作栈,指令集更小,编译器容易实现。
4)不需要硬件支持,可移植性更好,更好实现跨平台。
1)典型的应用是x86的二进制指令集:比如传统的PC以及Android的Davlik虚拟机。
2)指令集架构则完全依赖硬件,可移植性差。
3)性能优秀和执行更高效。
4)花费更少的指令去完成一项操作。
5)在大部分情况下,基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主,而基于栈式架构的指令集却是以零地址指令为主。
Java符合典型的栈指令集架构特征。Python、Go都属于寄存器指令集架构。
Java内存模型(Java Memory Model简称JMM)是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。
JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),用于存储线程私有的数据,而Java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝的自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,工作内存中存储着主内存中的变量副本拷贝,前面说过,工作内存是每个线程的私有数据区域,因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成。
Java内存模型&JVM内存区域模型
JMM与JVM内存区域的划分是不同的概念层次,更恰当说JMM描述的是一组规则,通过这组规则控制程序中各个变量在共享数据区域和私有数据区域的访问方式,JMM是围绕原子性,有序性、可见性展开。JMM与Java内存区域唯一相似点,都存在共享数据区域和私有数据区域,在JMM中主内存属于共享数据区域,从某个程度上讲应该包括了堆和方法区,而工作内存数据线程私有数据区域,从某个程度上讲则应该包括程序计数器、虚拟机栈以及本地方法栈。
可以这么说JMM就是CPU多级缓存架构的抽象!!!