一. 指令
我们平时在电脑上进行的操作或者是进行的一些编程,最后怎么转化成机器能够理解的命令呢,答案是将这些操作转化为二进制的指令,由计算机依次执行,这就涉及到了计算机的指令。
举一个最简单的例子,如何在计算机上实现” 3+14 “这样的简单的加法操作。
现在的主流操作系统都是64位的,但是用64位的指令演示较为麻烦且可见性不是很好,因此我们做一个简化的8位的指令用作演示:
1.1 指令
所谓指令,即指导 CPU 进⾏⼯作的命令,主要有操作码 + 被操作数组成。
其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可以是内存地址,也可以是寄存器编号等。
指令本⾝也是⼀个数字,⽤⼆进制形式保存在内存的某个区域中。
1.2 指令表
- 寄存器:CPU上的存储单元,存储的数据量较少,但是访问速度极快,比内存访问速度快3-4个数量级。
- RAM:内存;
1.3 "3+14"的计算流程
这是"3+14"转化位指令后的形式:
这里的执行逻辑也很简单,就是顺序执行:
地址 | 数据 | opcode(操作码) | 被操作数 | 指令含义 |
---|---|---|---|---|
0 | 00101110 | 0010 (LOAD_A) | 1110 (14号地址) | 将14号地址的数据加载到 A 寄存器中 |
1 | 00011111 | 0001 (LOAD_B) | 1111 (15号地址) | 将15号地址的数据加载到 B 寄存器中 |
2 | 10000100 | 1000 (ADD) | 01 (B寄存器) 00 (A寄存器) | 计算A、B寄存器的数据的和,并将结果存入A寄存器 |
3 | 01001101 | 0100 (STORE_A) | 1101 (13号地址) | 将数据从A寄存器写入RAM的指定地址 |
也就是说,完成这么一个加法操作需要依次执行:读入数据、加运算、存储数据三步。这对我们理解后续线程安全问题及其重要。
1.4 执行效率
我们前面说到,数据在寄存器上的读取速度是远远快于在内存上的读取速度的。因此,当初设计的每次运算都要去内存上读取数据并不合理。(很大程度上是受限于当年硬件水平较差,将 “执行” 和 “存储” 解耦合有利于降低硬件的设计成本)
实际上为了优化这个执行效率,CPU也设计了很多机制:
- 缓存
缓存的作用就是将计算好的数据,不是立马写回内存中,而是暂时写到缓存中,以便于下一次计算(下一次读数据直接在CPU的缓存中读取即可) - 流水线
流水线的作用就是在执行A的过程中,从内存中取指令B,在执行B的过程中,从内存中取指令C…即在等量的时间内进行更多的计算,这样也可以提高计算的效率。
1.5 总结
- CPU要执行的指令,存储在内存中。(冯诺依曼体系结构的基本设定,让 执行单元 和 存储单元解耦合)
- CPU想要执行指令,就要先取指令,再解析指令,然后才能执行指令
- 取指令需要从内存中读取指令到CPU的寄存器中(这个演示中没有体现出存储指令的寄存器,只体现了用于计算数据的寄存器),取指令的操作,相对于CPU执行计算,非常耗时、开销很大。(引入缓存、流水线来优化效率)
- CPU解析指令用到的指令表,不同架构的CPU的指令表不同(arm,x86),指令表细节,已经写死到CPU中了,CPU是很容易识别的。
- 指令在执行过程中,可能带有一些被操作数,不同的指令,操作数的含义和个数并不相同。
- CPU重要的参数:主频,近似看成1s内,CPU能执行的指令的个数。
比如我的电脑,基准速度(主频)位2.3GHz,即大概1s(准确来说是1个时钟周期)内能执行23亿( 2.3*(2^30) )次计算。
二.操作系统
操作系统实质上是一个软件,主要有两方面的职责:
- 管理各种硬件设备
比如说我们用的鼠标、键盘有很多种,而无论使用哪种,都不需要进行特殊设置即可使用。此时就由操作系统管理不同的硬件设备,给软件提供统一的api。 - 给其他软件提供稳定的运行环境
主流的操作系统主要有Windows、Linux、MacOs、IOS、Android。
思考一下:Java如何实现跨主机的特性的呢?
Java 程序被编译成字节码,这是一种中间形式的代码。字节码不依赖于特定的硬件和操作系统。不同主机上只要安装了对应的 Java 虚拟机(JVM),就可以运行字节码文件。
而像C/C++这样的语言,会被直接编译成系统能识别的代码,这就决定了C/C++不具有跨平台的能力。
2.1 系统内核
操作系统 = 内核 + 配套的应用程序(操作系统可以分为内核空间(内核态)和用户空间(用户态)。)
我们电脑上的各种运行程序都是运行在用户态的。但是这些程序,有时候需要针对系统提供的软硬件资源进行操作,这些操作,都不是在应用程序直接操作的。而是需要调用系统提供的API,进一步在系统的内核中完成这样的操作。
举一个简单的例子,去银行取钱:
我们去银行取钱,都是到办事窗口,由工作人员完成取钱这个操作。一方面是安全,另一方面是可靠。
同理,将这些针对系统提供的软硬件资源进行的操作交给系统内核来完成,避免由于软件设计的不合理、或者是一些bug将系统给搞坏。
这里所谓的软硬件资源其实也很好理解,比如说键盘、鼠标、显示器等IO设备、内存、硬盘(文件描述符表)、CPU、GPU等等。