计算机是如何工作的

目录

1、冯诺依曼结构体系

2、CPU

[2.1 CPU的组成](#2.1 CPU的组成)

逻辑门

门电路

[算术逻辑单元 ALU(Arithmetic&LogicUnit)](#算术逻辑单元 ALU(Arithmetic&LogicUnit))

[算术单元(Arithmetic Unit)](#算术单元(Arithmetic Unit))

[逻辑单元(Logic Unit)](#逻辑单元(Logic Unit))

ALU符号

寄存器(Register)和内存(RAM)

[控制单元 CU(Control Unit)](#控制单元 CU(Control Unit))

​编辑指令(Instruction)

CPU的基本工作流程

3、编程语言

程序(Program)

编程语言发展

[操作系统(Operating System)](#操作系统(Operating System))

核心概念:

进程/任务(Process/Task)

PCB的核心属性:


1、冯诺依曼结构体系

现在的计算机,大多都遵守冯诺依曼结构体系:

冯诺依曼体系也称为存储程序计算机 ,是现代计算机结构体系的基础。

核心思想

1.二进制:数字计算机的数值采用二进制,即以0和1来作为基础用于数值表示,这种表示方法简化了计算机的电路设计,提高了计算效率。

2.程序顺序进行:计算机按照程序的顺序执行,即预先编好程序,然后交给计算机,计算机按照程序中预先定义好的顺序来进行数值运算。

功能

1、输入:把需要的程序和数据送至计算机中。

2、存储:具有长期记忆程序,数据,中间结果及最终运算结果的能力。

3、处理:能够完成各种算术运算,逻辑运算和数据传送等数据加工处理操作。

4、控制:能够根据需要,来控制程序走向,并且能够根据指令控制其各部件协调操作。

5、输出:按照要求将处理结果输出给用户。

组成 :

运算器:用于完成各种算术运算,逻辑运算和数据传送等数据加工处理的操作。

控制器 :用于控制程序的执行,是计算机的大脑。 它与运算器一起组成计算机的中央处理器(CPU)。

存储器:用于记忆程序和数据,程序和数据以二进制代码形式不加区别地存放在存储器当中 ,**存放位置由地址决定。分为外存和内存,**用于存储数据(使用二进制方式进行存储)。

输入设备:如鼠标,键盘等,用于将数据和程序输入到计算机中。

输出设备:如显示器,打印机等,用于将数据或程序的处理结果展示给客户。

存储空间 :

硬盘 > 内存 >> CPU

对数据的访问速度:

CPU >> 内存 > 硬盘

2、CPU

2.1 CPU的组成

逻辑门

电子开关------机械继电器

通过电子开关,我们可以实现 1 位(bit) 的看似无用的逻辑运算,但至少工作起来了。

门电路

使用电子开关可以构建门电路,它可以实现1位(bit)的基本逻辑运算。

算术逻辑单元 ALU(Arithmetic&LogicUnit)

ALU是计算机中进行算术,逻辑运算的核心部件,是计算机的数学大脑。接下来,我们可以用上面构建的逻辑门来完成一个ALU。

补充知识:进制的理解

算术单元(Arithmetic Unit)

负责计算机里的所有数字操作。接下来会实现一个8位(bits)的加法器,来演示整个过程。

这样,我们就有了一个8位(bits)的加法器。算术单元支持的操作并不止这些,通过继续组合逻辑门,算术单元可以做到加减乘除甚至更多的算术运算。

逻辑单元(Logic Unit)

逻辑单元主要用来进行逻辑操作,最基本的操作是与(&),或(|),非(!),异或(^),但不只是一位(bit)数的比较。

ALU符号

经过基本的逻辑门电路,我们实现了一个8位(bits)的ALU,甚至比Intel74181还强大(Intel74181只是一个4位的ALU)。

寄存器(Register)和内存(RAM)

光有ALU还是不够的,无法为ALU提供存储的部件。所以还需要存储的制作。

可以利用门锁来构建需要的寄存器和内存。

内存的构建比寄存器复杂一些,但基本原理一致。如此构建的内存被称为RAM,支持O(1)时间复杂度访问任意位置的数据,这也就是数组下标访问操作是O(1)的硬件支持。

控制单元 CU(Control Unit)

有了ALU,能够存储数据,但还是不足以让我们的计算机工作起来,我们需要有一个部件来只会ALU进行何种运算,这个部件就是控制单元(CU)。

指令(Instruction)

指令:指导CPU进行工作的命令,主要有操作码和被操作数组成。

其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可能是内存地址,也可能是寄存器编号等(这个要看当前执行指令的场景)。

指令本身也是一串二进制数字,保存在内存的某个区域中。

这是一种CPU的指令表(不同CPU的指令表不同),稍候将通过该指令表来讲解CPU的工作流程:

CPU的基本工作流程

下面将演示CPU工作的过程:

我们写好的java程序,都是先编译成可执行文件(exe,包含了这个程序运行时要执行的指令和依赖的数据),当点击运行的时候,操作系统会把要执行的指令和依赖的数据加载到内存中,在CPU中存在一个"程序计数器"(CPU中存在的一个特殊寄存器),用来保存接下来要从那个内存位置来执行指令,在exe文件加载到内存后就被系统自动设置好,exe刚加载好时,程序计数器默认为0,(即从0号地址开始执行),随着指令的执行,这里的值也会进行更新,默认情况下,就是+1(顺序执行),如果遇到跳转类语句,就会被设为其他的值,进行跳转。

执行指令的三个重要阶段:

1、取指令:CPU从内存中读取指令内容到CPU内部(会有专门的寄存器来保存读取到的指令,上图中的寄存器仅供参考)。

2、分析指令

3、执行指令

以上面两幅图的指令表和指令来分析CPU工作的过程:

此时程序计数器的数字为0,即从0位置开始执行指令: 0010 1110

1、取指令:取到0010 1110。

2、分析指令:前四位0010为操作码,查表发现0010是LOAD_A操作,用于将数据加载到A寄存器,后面的操作数为要操作数据的内存地址,也就是把地址为1110(十进制为14)的数据读取到寄存器A中。

3、执行指令:把内存地址为14对应的数据0000 0011(十进制为3)放到寄存器A中。
程序计数器++,执行地址为1的指令:0001 1111

1、取指令:取到0001 1111指令。

2、分析指令:0001为LOAD_B 操作,也就是将1111(十进制为15)这个地址对应的数据加载到B寄存器中。

3、执行指令:把地址为15对应的数据0000 1110(14)存储到寄存器B中。
程序计数器++,执行地址为2的指令:1000 0100

1、取指令:取到1000 0100指令

2、分析指令:1000对应ADD操作,也就是计算两个指定寄存器的数据的和,并将结果放入第二个寄存器,后面的操作数两个两位的寄存器id ,00为A寄存器,01为B寄存器。所以就是将B寄存器中的数值与A寄存器中的数值相加,然后将结果存放到A寄存器(00)中。

3、执行指令:A寄存器中的数据+B寄存器中的数据 = 3+14 = 17放到寄存器A中。
程序计数器++,执行地址为3的指令,0100 1101

1、取指令:取到0100 1101指令

2、分析指令:0100对应 STORE_A操作,将数据从A寄存器写入RAM指定地址,后面的操作数是要存放数据的内存地址,将A寄存器中的数据(17)存储到1101(13)地址中

3、执行指令:将17存入13号内存中(即将里面的数据变为0001 0001)
程序计数器++,执行地址为4的指令。对应表中数据为0000 0000,表示程序执行结束。

上面的过程就完成了14+3的完整过程。

执行的指令周期:当然,计算机中的CPU不会像刚刚那样,靠自己来驱动这个周期的运转,而是靠背后的一个时钟来进行周期驱动的。

总结:ALU+CU+寄存器+时钟就组成了CPU(中央处理器)。

CPU补充认识 :

**定义与功能:**CPU,是计算机系统的核心部件,负责执行计算机的基本算数,逻辑,控制和输入输出操作指令。是计算机的运算和控制核心,是信息处理,程序运行的最终执行单元。

CPU制作工艺非常精密,现今出名的公司:X86架构:(1)因特尔 (2)AMD arm架构:(1)苹果(2)高通

CPU的核心指标:核心数和频率

**1、核心数:CPU内部集成的物理核心数量。**多核CPU可以同时处理多个任务,提高整体性能。

线程数 :是 CPU 能够同时处理的线程数量 。一般先进的CPU技术(如Intel的超线程技术)允许每个物理核心处理两个或者更多的线程,被称为是逻辑核心 / 逻辑处理器 。因此,线程数可能大于等于核心数 。如图,我的电脑为10核心,16线程的CPU。(大小核技术架构)。

单核处理器与线程:一个核心只能处理一个线程。

超线程技术:一个核心能处理多个线程 。

2、主频: CPU的时钟频率,表示CPU在单位时间内(s)发出的脉冲数。 它决定了**CPU的运算速度,主频越高,CPU运算速度越快。**通常以GHz为单位。

基准速度:下限速度。

**实时频率/睿频(对应图中的速度,会动态变化的):**随着频率提升,消耗的电量更高,发热更多...

CPU的频率往往都是动态变化的,会根据任务量动态调整。

计算机都由"功耗墙",CPU温度达到一定的阈值(105摄氏度),自动降频。(散热工作做好,可以让频率达到更高的水准 --> 超频)

3、指令:程序语言(比如:C,C++,Java)编写的程序,最终都要被翻译为"CPU上执行的二进制指令"(机器语言(二进制表示)/汇编语言)。

4、寄存器:位于CPU的内部,是CPU内部存储数据的部分,具有非常高的存取速度 ,被用来暂时的存储数据 ,**指令地址和状态信息,**以便于CPU在执行指令的时候,能够快读访问到这些数据。

但是存储数据,主要还是靠**内存和硬盘 ,**实际上,CPU在运算中,需要先把数据从内存中读到CPU中,才能进行运算。寄存器的空间往往为几 KB,比内存更小,速度比内存更快,成本也比内存更高,断电后会丢失。因此,CPU在计算的时候,就需要反复的从内存加载数据,效率比较有影响。

现代CPU引入了缓存来解决这一问题。

某个内存的数据,经常使用,寄存器又存不下,就可以放在缓存中。数据使用的频率越高,就往L1放,没那么高,就L3,中间就L2。

3、编程语言

通过上文我们已经大致了解了什么是CPU?什么是内存?下面我们来尝试还原Java是如何和CPU指令对应起来的。

程序(Program)

程序:一组指令以及这组指令要处理的数据。狭义上来讲,程序对我们来说,通常表现为一组文件。

程序 = 指令 + 指令要处理的数据。

早期编程:

很久以前,那还是我用Win98的时候有次我系统崩溃了,因为我是电脑白痴,我朋友给我介 绍了⼀个高手来帮我修电脑。

他看了⼀下电脑,问我有没有98的盘,我说没有。 他想了⼀下,叫我把固定电话拿给他,我想修电脑要电话干什么,但人家是高手,我也不好 说什么,就把电话拔下来给他了。

他把电话线空着的⼀头接在电脑的⼀个插孔内,然落后入了dos,然后就开始在电话上不停的 按着键,他按键的速度异常快,但是只按0,1两个键,我搞不懂这有什么用,但也不敢问, 看了半个多小时,他还是不停的按这两个键,我徐徐的有些困,我问他这东西要搞多久,他说要几个小时,我给他倒了杯茶,就⼀个⼈去隔壁睡觉了。

醒来的时候,⼀看已经过了4个多小时,我起⾝到隔壁,看见他正在98里面调试,过了⼀会 儿,他说,你试试,我坐上椅子用了⼀下,真的好了,我当时也不懂电脑,谢过人家就走 了。 后来我慢慢对电脑有了了解,终于了解,原来当时那位高手是用机器语言编了⼀个98系统, 我后来问我朋友那位高手的下落,我朋友说前几年去了美国之后,杳无音讯...
这是一个早先流传的趣味小故事,当然这件事不一定是真实的。但最早的电脑,要进行编程,是真的需要用0 1 进行编程的( Σ ( っ ° Д °;) っ)。
下图为ALtair 8800 计算机,是最早的一批微型计算机。用户需要控制开关,一个bit一个bit地将程序录入电脑中。
如果要求计算机的用户都必须使用二进制编程,那大家都要疯掉了,这可是一件门槛太高的事情了。所以编程语言应运而生了。

编程语言发展

为了提升编程效率,最早创造了汇编语言的概念。其实汇编语言和机器语言(也就是指令)直接是完全一一对应的,只是相对于 0 、 1 这些数字,发明了一些帮助人类记忆和理解的符号将其对应起来,也就是我们上面看到的类似 LOAD_A 、 LOAD_B 等。程序员完成编程之后,需要使用汇编器( assembler )将汇编语言翻译成机器语言。
虽然汇编降低了程序员的记忆成本,但要求程序还是必须掌握计算机硬件的所有知识,而且随着计算机厂商越来越多,一次编写的程序往往只适用于一类计算机。这个是远远不够的,所以更为高级的语言诞生了,高级语言屏蔽了硬件细节,让程序员可以站在更高的层面上思考自己的业务。这里以 C 语言为例,程序员完成程序的编写之后,需要使用编译器(compiler )和连接器( linker )将程序翻译成汇编语言,再借助汇编器变成最终的机器语言。
借助封装的思想,我们学习编程变得越来越容易。不过有利则有弊,高度的抽象,导致很多的程序员把计算机视为一个黑箱,完全无法理解自己的程序是如何工作起来的,希望我们大家不要做这种程序员。

注意:高级语言的一条语句(Statement)往往对应很多条指令(Instruction)才能完成。(如count++,需要把count这个变量放到寄存器中(LOAD_A),再++(ADD),然后再返回内存中(STORE_A))。

操作系统(Operating System)

操作系统是一组做计算机资源管理的软件的统称。目前常见的操作系统由:Windows系列,Unix系列,Linux系列,OSX系列,Android系列,iOS系列...

每个系统之间运行的程序都是不同的,即,系统之间是不兼容的。也就是说,我在windows写了一个程序,它是不能直接拿到Linux这些其他地系统上运行的(系统内部的API存在差距).

但是对于Java这种跨平台性的语言,虽然在Windows和Linux有着不同的JVM,但是这些JVM是兼容同样的字节码

核心概念:

操作系统的作用:1、管理不同的硬件设备。2、给软件提供稳定的运行环境(让程序之间不会互相干扰)。(抽象,封装)。

操作系统的内核:操作系统最核心部分的功能模块。一个完整的操作系统 = 内核+应用程序。

操作系统会管理各种的硬件设备处理器,主存,I/O设备。

操作系统给应用程序提供API(接口),让应用程序调用,从而来完成不同的操作。

例如:Sysytem是Java标准库提供的函数。JVM中,为了实现System,就会调用操作系统提供的API,执行(Linux对应的系统api叫做write)调用系统API,程序就会进入到系统的内核中执行,此时系统就会操作对应的硬件设备来完成打印操作,操作系统管理的硬件设备有很多。

不是系统直接操作硬件,而是硬件厂商,会提供对应的"驱动程序",操作系统其实就是通过驱动程序,间接的操作硬件设备的。

进程/任务(Process/Task)

进程:正在运行的应用程序。操作系统内核的重要功能:进程管理。

进程是系统分配资源的基本单位!!!

应用程序的两种状态:

1、没有运行时是一个exe文件,待在硬盘里,为可执行文件。

2、运行的时候,exe就会被加载到内存中,并且 cpu 执行里面的指令,即进程。进程都是通过操作系统来执行的,执行进程里的指令需要硬件资源。

那么进程是如何进行管理的呢?->PCB(Process Control Block)--进程控制块

1、先描述: 通过结构体或类,把进程的各种属性表示出来(Linux系统使用PCB来描述进程信息的)。

**2、后组织:**使用一定的数据结构,把这些结构体/对象串到一起。(Linux系统使用链表)。

PCB的核心属性:

1、PID:进程标识符

进程的身份标识:简单的不重复的整数,后续要针对某个进程进行操作,就可以拿PID进行区分了。

2、内存指针

描述进程依赖的指令和数据都在内存中的那个区域 。在运行exe程序之后,操作系统就会读取exe中的指令和数据,加载到内存中(内存地址),有了内存地址,就知道进程对应的指令和数据在系统的那个位置。侧面的表现出:进程的执行,是需要一定的内存资源的

3、文件描述符表

详细描述了文件使用了硬盘的详细情况。

操作系统调度进程的关键:分时复用!!!

现在我们所使用的操作系统都是多任务系统,可以同时运行多个进程。分时复用:就是同一时刻,CPU执行了多条指令,但是由于这些指令切换的速度非常快,看起来就像是同一时间执行。------并发执行。

现在计算机使用的是多核CPU(一个CPU能完成多个CPU完成的工作,相当于多个CPU),也就是我们可以在不同的CPU上,同时执行不同的指令------并行执行。

因为并发执行/并行执行我们用户并不能直观感受到,所以当前我们所说的并发就是并发+并行运行的。

为了完成线程的调度,PCB提供了很多属性:

**进程状态:**描述一个进程能否去CPU上执行。

就绪状态:随时可以调度到CPU上执行。

堵塞状态:不方便调度到CPU上执行,比如进行输入操作,需要等待用户输入才能继续执行。

进程的优先级: 调用进程的顺序,控制进程在CPU上待的时间的长短。

**记账信息:**针对每个进程,占据多少CPU时间进行统计,操作系统会根据这个统计结果来进一步调整调度的策略。

**上下文:**支撑进程调度的重要属性(相当于游戏里的存档、读档),保存上下文:把CPU关键寄存器的数据保存到内存中,恢复上下文:把内存中的关键寄存器的数据加载到CPU的对应寄存器。

相关推荐
小陶来咯1 小时前
【高级IO】多路转接之单线程Reactor
服务器·网络·数据库·c++
^小桃冰茶2 小时前
CSS知识总结
前端·css
运维@小兵2 小时前
vue注册用户使用v-model实现数据双向绑定
javascript·vue.js·ecmascript
巴巴_羊3 小时前
yarn npm pnpm
前端·npm·node.js
chéng ௹4 小时前
vue2 上传pdf,拖拽盖章,下载图片
前端·css·pdf
嗯.~4 小时前
【无标题】如何在sheel中运行Spark
前端·javascript·c#
A_aspectJ7 小时前
【Bootstrap V4系列】学习入门教程之 组件-输入组(Input group)
前端·css·学习·bootstrap·html
兆。7 小时前
电子商城后台管理平台-Flask Vue项目开发
前端·vue.js·后端·python·flask
互联网搬砖老肖7 小时前
Web 架构之负载均衡全解析
前端·架构·负载均衡
Xena_Networks8 小时前
SierraNet协议分析使用指导[RDMA]| 如何设置 NVMe QP 端口以进行正确解码
linux·服务器·网络