前言
在并发编程中,首先我们需要了解一下底层的才做系统相关知识,那么我们从最早的计算机模型及其后期发展去探究计算机的底层涉及。
计算机模型
对于计算机而言,很多计算机模型都是基于-冯诺依曼计算机模型而来的,冯诺依曼计算机模型科班出身应该都有了解,实际上次模型有五大基本的部分组成,一下为五个部分的名称。
- 存储器、2. 运算器、3. 控制器、4. 输入设备、5. 输出设备
冯诺依曼计算机模型
如下图所示:
根据冯诺依曼计算机模型及实现,逐步演变成现今的计算机模型结构。
现今的计算机模型
如下图所示:
可以看到相较于冯诺依曼计算机模型,现今的计算机模型十分复杂,从图中可以看出cpu与内存条及外部设备的数据交互主要是依赖于I/O桥。
cpu指令结构
由于cpu内部的存储空间十分有限,所有cpu的运作需要频繁的和内存进行数据交互,cpu内存机构主要有一下几种:
- 控制单元:控制单元是cpu的控制调度中心,协调计算机工作的核心,通俗的理解可以是java语言中用于进行控制的关键字,如:while、if、for等等,做一下控制操作。
- 运算单元:主要用于计算。
- 存储单元:存储一些来自内存的数据及指令或者存储一些临时结果存储,类似寄存器或者cpu的缓存。
cpu指令结构如下图:
cpu缓存结构
cpu缓存结构大致如图所示:
说明:如我们所知,cpu中存在三级缓存,L1、L2、L3,是为了保证cpu告诉运转的过程中减少通过I/O桥与外部设备或者内存进行数据交互,虽然计算机访问效率很高,但cpu访问内存和访问自己缓存的时间是相差百倍的,所以使用了三级缓存提高效率。 现今cpu可以有多核,那么在一个cpu中的L1、L2缓存是cpu中每个核独享的,而L3则是cpu所有核共享的。
存储器存储空间大小:内存>L3>L2>L1>寄存器;
存储器速度快慢排序:寄存器>L1>L2>L3>内存;
cpu中的缓存行
缓存行:缓存是由最小的存储区块-缓存行(cacheline)组成,缓存行大小通常为64byte。
目前针对于64位操作系统来说 如下图我的电脑,L1缓存大小是384kb,而cacheline = 64byte,那么就是L1里有384 * 1024/64个cacheline
CPU为何要有高速缓存
CPU在摩尔定律的指导下以每18个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及CPU。这就造成了高性能能的内存和硬盘价格及其昂贵。然而CPU的高度运算需要高速的数据。为了解决这个问题,CPU厂商在CPU中内置了少量的高速缓存以解决I\O速度和CPU运算速度之间的不匹配问题。
在CPU访问存储设备时,无论是存取数据抑或存取指令,都趋于聚集在一片连续的区域中,这就被称为局部性原理。
时间局部性(Temporal Locality):如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。
比如循环、递归、方法的反复调用等。
空间局部性(Spatial Locality):如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。
操作系统内存管理
操作系统的内存实际上是分为两部分:用户空间、 内核空间,如:以内存空间为4G大小为例子,用户空间的内存大小:内核空间的内存大小 = 1 :3,之所以分为两个空间来管理是为了更安全的管理内存,防止用户进程修改系统文件,防止重要信息的泄漏。 分为两个空间后cpu的调度的基本单位是线程,可划分为:
-
内核线程模型(KLT)
-
用户线程模型(ULT)
内核线程模型: 内核线程:是由操作系统管理用户线程,内核保存线程的状态和上下文信息,线程阻塞不会引起进程阻塞。在多处理器系统上,多线程在多处理器上并行运行。线程的创建、调度和管理由内核完成。
用户线程模型:
用户线程:用户应用去实现线程的调度,不依赖操作系统,应用提供创建、同步、调度和管理线程的函数来控制用户线程。不需要用户态/内核态切换,速度快。内核对ULT无感知,线程阻塞则进程(包括它的所有线程)阻塞。
在java中是用的是KLT模型那么怎么去验证呢? 初始化的时候可以看到我本机的线程数量在4100左右,我使用java创建500个线程并sleep,这样在我的线程数量就会迅速增加500个,停止应用线程会减少。
创建前:
创建后: