当前位置: 首页 > news >正文

计算机是如何工作的

目录

1.冯诺依曼体系

 (1)存储器

 (2)认识CPU

 (3)CPU执行指令的过程

2.操作系统

(1)详解内核

(2)详解进程 


1.冯诺依曼体系

现在我们所使用的计算机大多都遵守冯诺依曼体系结构

  • CPU 中央处理器 : 进行算术运算和逻辑判断
  • 存储器:分为外存和内存,用于存储数据(使⽤⼆进制⽅式存储)
  • 输⼊设备:用户给计算机发号施令的设备.
  • 输出设备:计算机个用户汇报结果的设备.

 (1)存储器

定义和功能:存储器是计算机系统中的记忆设备,用于存放程序和数据。计算机中的全部信息,包括输入的原始数据、计算机程序、中间运行结果和最终运行结果,都保存在存储器中。存储器会根据控制器指定的位置存入和取出信息。

存储器的分类:

  • 内存(与CPU直接交换信息)
  • 外存(用于储存不是实时成像任务中获取的图像,如硬盘、光盘、U盘等。)

内存:存储空间小,访问速度快,成本高,掉电后数据丢失

硬盘:存储空间大,访问速度慢,成本低,掉电后数据仍在.
 

 (2)认识CPU

定义与功能:CPU,即中央处理器,是计算机系统的核心部件,负责执行计算机的基本算术、逻辑、控制和输入/输出(I/O)操作指令。它是计算机的运算和控制核心,是信息处理、程序运行的最终执行单元。

CPU的制作工艺非常精密,现今较为出名的公司:

(1)英特尔 (2)AMD  (3)高通(手机)

CPU的核心参数:

两个重要指标是核心数和频率

  1. 核心数:指CPU内部集成的物理核心数量。多核心CPU可以同时处理多个任务,提高整体性能。
    线程数:线程数是CPU能够同时处理的线程数量。一些先进的CPU技术(如Intel的超线程技术)允许每个物理核心处理两个或更多的线程,这被称为逻辑核心或线程。因此,线程数可能大于或等于核心数。

    我们可以打开任务管理器在性能里查看自己电脑的核心数,此时我的电脑是16核(有几个方框就有几个核心数)  也就是8核16线程(一个核心可以执行多个线程)
  2. 主频:主频是CPU的时钟频率,表示CPU在单位时间内(秒)发出的脉冲数。它决定了CPU的运算速度,主频越高,CPU的运算速度就越快。主频通常以GHz(吉赫兹)为单位。

    基准速度:可以认为是下限速度
    实时频率/睿频(对应图中的速度,它是动态变化的):随着频率提升,消耗的电量更高,发热更多~~
    CPU的频率往往是动态变化的,会根据任务量动态调整

    计算机都有"功耗墙",cpu温度达到一定阈值(105摄氏度),自动降频
    散热工作做好,可以让频率达到更高的水准  =>  超频
  3. 指令: (C / Java语言,编程语言写的程序,最终都要被翻译成"cpu上执行的二进制指令"
    指令(机器语言(用二进制表示)或叫做汇编语言)就是cpu干活,完成任务的基本单位.
  4. 寄存器:寄存器就是cpu内部存储数据的部分,位于CPU内部,具有非常高的存取速度。它被用来暂时存储数据、指令地址和状态信息,以便CPU在执行指令时能够快速访问这些数据。

    存储数据,主要是靠内存和硬盘,实际上, cpu在运算的时候,需要先把数据从内存读到cpu里,才能进行运算.

    存储空间往往为几kb,比内存更小,速度比内存更快,成本也比内存更高,断电后会丢失
    因此 cpu在计算的时候就需要反复的从内存加载数据,效率比较有影响

    而现代CPU引入了缓存来解决这一问题
    某个内存的数据,经常使用,寄存器又存不下就可以放到缓存中.
    数据使用的频率越高,就往L1上放,没那么高放L3,中间的就放L2

 (3)CPU执行指令的过程

一个CPU能执行哪些指令,可以认为是cpu最初设计的时候,就已经写死了.(确定好了)存在一个"表格"描述了都有哪些指令.

说明:

此处假设每个指令只有8 bit(实际要更长)
8 bit的指令,分成两个部分
4 bit是操作码(opcode)表示指令是干啥的,后4 bit是操作数(类似于参数)

  • RAM表示内存,全称是随机访问存储器
  • AB寄存器名字是虚构的,实际上每个寄存器都有真实的名字,如:AX,BX,CX,DX
  • 两位表示寄存器ID,这里我们约定A寄存器是00,B寄存器是01

像我们写好的C语言和Java这样的程序是先编译成可执行文件(.exe,包含了这个程序运行时要执行的指令和依赖的数据),在我们点击运行的时候,操作系统就会把exe加载到内存中

在CPU中存在一个特殊的寄存器“程序计数器”,用来保存接下来要从哪个内存位置来执行指令,在exe加载到内存后就能被系统自动设置好,也就是说程序计数器此时会默认置为0,从0号地址开始执行,同时随着指令的执行,这里的值,也会随着更新.默认情况下,就是+1自增过程.(顺序执行)如果遇到"跳转类语句" (if, while, for,函数调用.....)会被设为其他的值
 

执行指令的三个重要阶段

  1. 取指令(cpu从内存中读取到指令内容到cpu内部.(有专门的寄存器保存读取到的指令,不是上面说的a b寄存器)
  2. 分析指令(识别出这个指令是干啥的,以及对应的功能和操作数)
  3. 执行指令

初始情况下,我们从0地址开始读取数据,我们以0010 1110为例来执行这条指令

  1. 取指令:取到0010 1110这条指令
  2. 分析指令:前四位0010表示操作码,表示用来干什么,我们通过查指令表发现0010是LOAD_A操作,用于将数据加载到A寄存器,也就是把1110(十进制为14)地址的数据读取到A寄存器中
  3. 执行指令:把14的内存地址对应的数据0000 0011存储到寄存器A中

        第一条指令执行完毕,系统会自动把程序计数器中的值++从0 ->1

程序计数器++,执行地址为1的地址,对应表中数据为 0001 1111

  1. 取指令:取到0001 1111这条指令
  2. 分析指令:0001对应LOAD_B操作,也就是将1111(十进制为15)这条地址对应的数据加载到B寄存器中
  3. 执行指令:把15的内存对应的数据0000 1110存储到寄存器B中

程序计数器++,执行地址为2的地址,对应表中数据为1000 0100

  1. 取指令:取到1000 0100这条指令
  2. 分析指令:1000对应ADD操作,也就是计算两个指定寄存器的数据的和,并将结果放
    入第二个寄存器,01为B寄存器,00为A寄存器,所以就是将B寄存器中的数值与A寄存器中的数值相加存放到A寄存器中
  3. 执行指令:A寄存器中数据为3 + B寄存器中的数据14 = 17(0001 0001)存放在A寄存器中

程序计数器++,执行地址为3的地址,对应表中数据为0100 1101

  1. 取指令:取到0100 1101这条指令
  2. 分析指令:0100对应STORE_A操作,将数据从A寄存器写入RAM的指定地址,将A寄存器中的0001 0001(17)存储到1101(13)地址中
  3. 执行指令:13号内存中的数据变为0001 0001 

程序计数器++,执行地址为4的地址,对应表中数据为0000 0000,表示程序执行结束

上述代码,完成了3+14的过程.为了进行相加运算,对于CPU来说,不是一件那么容易的事情.


对于Java程序员来说,一个比较典型的指令级开发的场景,给程序打热补丁
比如,做一个服务器开发,这个服务器非常重要,不能重启~~(最多是在某些特定时间才能重房启……发现服务器存在严重bug 但是又不能修复bug重启程序~~此时就可以考虑"打热补丁"
写的程序的指令,也是在内存中的,对应的有bug的代码,也是其中的一段指令
找到有bug 的代码指令,直接修改这里的指令,修改成没有bug的版本,或者在这个指令前加上跳转指令,让有bug逻辑不去执行,而是去执行新增的一个正确的指令….... 

2.操作系统

(1)详解内核

常见的操作系统:

(1)Windows (2)Linux (3)Mac os (4)Android (5)IOS

每个系统之间运行的程序都是不同的,也就是系统之间是不兼容的

windows 写了一个程序,这个程序是不能直接拿到Linux等其他系统上运行的(系统内部的API存在差异)

但是对于Java来说是具有跨平台性的,比如在Windows和Linux有着不同的JVM,但是这些JVM是兼容同样的字节码

操作系统的核心概念:

 一个操作系统需要做的最重要事情就是管理

  1. 管理不同的硬件设备(计算机能接入很多的设备.扫码枪,医疗设备,B超超声机...)
  2. 给软件提供稳定的运行环境(在同时运行很多程序时要做到程序之间不相干扰)

以上两点也被称为“操作系统内核”,是核心功能的集合。一个完整的操作系统就是内核+配套的应用程序

操作系统的定位:

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

操作系统给应用程序提供API,让应用程序调用来完成不同的操作

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

操作系统管理的硬件设备有很多
不是系统直接操作硬件,而是硬件厂商会提供对应的“驱动程序"操作系统其实是通过驱动程序,间接的操作硬件设备的
例如,罗技鼠标多个按键功能的设置,操作系统控制驱动程序简介操作硬件设备进而操作应用程序

操作系统中内核的重要功能:

进程管理

所谓进程(进程process/任务task)就是正在运行的应用程序

应用程序有两种状态:

  1. 没有运行时是一个exe文件,呆在硬盘里,即可执行文件
  2. 运行的时候, exe就会被加载到内存中,并且cpu执行里面的指令了.即进程

 进程都是通过操作系统来执行的,执行进程里的指令需要硬件资源

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

由于系统上的进程较多所以需要进行管理,那进程如何进行管理呢?

  1. 描述 :通过结构体或类,把进程的各种属性表示出来(对于Linux操作系统来说,使用称为"PCB"(进程控制块)这样的结构体来描述进程信息的.)
  2. 组织 :通过数据结构,把多个上面的结构体,穿起来,并进一步的进行各种增删改查(简单认为,通过链表的方式,把上述多个PCB串到一起,但实际更复杂)

    创建新的进程就相当于创建了一个PCB结构体并插入到链表中
    销毁进程就相当于,删除某个PCB对应的链表节点并释放资源
    查看进程列表,就是在遍历这个链表,依次显示出对应的信息~~

(2)详解进程 

详解PCB(进程控制块)

PCB是一个非常复杂的结构体,里面包含着非常多的属性,重要的有以下几个

  1. PID进程的标识符
    同一时刻,一个机器上的多个进程之间, PID唯一的,不会重复.系统内部的很多操作,都是通过PID找到对应的进程的.
  2. 内存指针
    描述进程依赖的指令和数据都在内存的哪个区域~~
    操作系统,运行exe,就会读取exe 中的指令和数据,加载到内存中.(内存地址),有了内存地址就知道进程对应的指令和数据在系统的哪个位置
    侧面表示出,进程的执行,需要一定的内存资源的
  3. 文件描述符表(顺序表/数组)
    用来描述打开了哪些文件,对应到硬盘上的数据,进程中,打开了某个文件,就会在顺序表中添加一项~
    侧面表示出,进程的执行,需要一定的硬盘资源的
  4. 进程的状态,优先级,上下文,优先级统称为进程的调度
    计算机上同时存在百八十个进程,这些进程是需要同时进行的,如何执行呢?
    CPU负责执行,CPU每个核心,可以执行一个进程.(执行进程里的指令,执行的过程就是取指令,分析指令,执行指令),上文中说道我的电脑是8个物理核心16个逻辑核心,一个线程就可以执行一个进程,那也就是说我的电脑可以同时执行16个进程,那其他线程怎么办呢?

    操作系统,进程调度的关键,"分时复用"
    现如今的操作系统,都是“多任务系统”,同时可以运行多个进程
    分时复用简单来说就是同一时刻由于切换速度很快相当于cpu同时运行多个进程
    站在宏观角度(人),同时执行,"并发执行"   (并发简单说就是宏观上看起来是同时,但微观上是一个接一个的执行,只不过执行速度很快,感觉不到而已)

    现在又有了多核心cpu, 此时,每个核心和核心之间,微观上也能同时执行不同的进程,
    微观上并行执行,叫做“并行执行”

    并发/并行,都是操作系统内核统─调度的,程序员/普通用户,感知不到
    因此,平时也把并行和并发,统称为"并发"对应的编程的手法,也就称为"并发编程"

    进程的状态,优先级,上下文,优先级就是用来支持并发执行调度过程的
  • 进程状态
    就绪状态的进程,是可以随时被调度到CPU上执行指令的~~

    阻塞状态的进程,无法调度到CPU上执行.之所以阻塞,是因为要做一些其他的工作,比如进行IO操作(读写硬盘/读写网卡.…)
    我们之前学过的scanf,Scanner输入就是典型的阻塞状态,他会从控制台读取输入,等待I/O产生的阻塞,代码执行到这样的语句时代码就"卡住",当你输入数据后才会继续执行
  • 进程的优先级
    也就是cpu获取资源的先后顺序问题
  • 进程的上下文
    分时复用,一个进程执行一会之后,就要从cpu上调度走
    过一段时间,还会调度回cpu,就要沿着上次执行的结果(把之前执行的中间结果(各种cpu寄存器中的值)保存起来,以备下次使用),继续往后执行
  • 进程的记账信息
    优先级的加持之下使不同的进程,吃到的资源,差异越来越大了
    操作系统,统计每个进程,在CPU上执行的时间根据这个来进一步的调整调度的策略

 

相关文章:

  • LabVIEW电路板性能与稳定性测试系统
  • thinkadmin发邮件功能如何设置?怎么使用?
  • Vue 组件之间的通信
  • 嵌入式学习——网络编程(TCP)——day31
  • 短视频矩阵系统----可视化剪辑独立开发(采用php)
  • [STM32]定位器与PWM的LED控制
  • SQL数据库性能优化
  • 【QT】QFont字体设置
  • Ubuntu为sudo指令设置免密码
  • 【FAS】《Liveness Detection on Face Anti-spoofing》
  • 【Python】实现极致:克服PyInstaller打包挑战,解决libpython3.10.so.1.0库丢失难题
  • 教师常用小程序分享
  • AlaSQL.js:用SQL解锁JavaScript数据操作的魔法
  • 十、C语言:数据存储(大端小端存储,整型、浮点型存储)
  • Hadoop3:MapReduce源码解读之Map阶段的TextInputFormat切片机制(3)
  • python3.6+scrapy+mysql 爬虫实战
  • egg(89)--egg之redis的发布和订阅
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • ng6--错误信息小结(持续更新)
  • Web标准制定过程
  • windows下如何用phpstorm同步测试服务器
  • 笨办法学C 练习34:动态数组
  • 初识 webpack
  • 对超线程几个不同角度的解释
  • 反思总结然后整装待发
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 深度学习在携程攻略社区的应用
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 智能网联汽车信息安全
  • 终端用户监控:真实用户监控还是模拟监控?
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 扩展资源服务器解决oauth2 性能瓶颈
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​学习一下,什么是预包装食品?​
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • #在 README.md 中生成项目目录结构
  • (1)(1.11) SiK Radio v2(一)
  • (Forward) Music Player: From UI Proposal to Code
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (过滤器)Filter和(监听器)listener
  • (六)Flink 窗口计算
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (七)Appdesigner-初步入门及常用组件的使用方法说明
  • (四)Linux Shell编程——输入输出重定向
  • (自用)仿写程序
  • ***原理与防范
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET WPF 抖动动画
  • .NET 表达式计算:Expression Evaluator
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .net反混淆脱壳工具de4dot的使用