我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。
计算机包含输入设备、输出设备、存储器、中央处理器(运算器+控制器) 截至目前,我们所认识的计算机,都是有一个个的硬件组件组成的。磁盘属于外存,具有永久性存储能力。CPU作为计算机的核心,负责计算,速度最快,寄存器次之,内存在次之,而外设是较慢的。
其中:
输入设备:键盘、磁盘、网卡、鼠标、摄像头、话筒等
- 计算机的本质是计算数据,要计算数据第一步是想办法把数据交给计算机,需要有对应的设备来采集相应的数据,这就需要使用输入设备。
输出设备:显示器、磁盘、网卡、声卡、音箱、打印机等
- 计算机的作用是服务用户,计算完数据后需要将数据输出给用户,这就需要输出设备
存储器:内存
CPU:运算器、控制器
- 计算机的本质工作是计算,CPU就是用来计算的,这是必不可少的。比如我们今天买了一部手机,这个手机没有芯片,那也只能当作移动硬盘来用。
- 注意:同种设备可能即使输入设备,也是输出设备如磁盘、网卡等
- 内存需要从磁盘中读取数据(为什么不是CPU读取下面会讲),这时它是输入设备,CPU处理好的数据需要经由内存放入磁盘,这里它就是输出设备。
- 我们在聊天软件如微信、QQ聊天时,别人将信息通过网卡传给我们,这时本地的网卡对于我们就是输入设备,我们将信息通过本地的网卡传给别人,此时本地的网卡就是输出设备。
- 存储器不是磁盘,是内存,之后会反复用到内存
冯诺依曼体系结构里的存储器一般指的是内存。我们都知道,写好的软件在编译好后,要运行,必须要先加载到内存,但是为什么要先加载到内存呢?
因为CPU在和存储器的交互中,要不断读取数据,这些数据必须是在内存里面,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备),但是你编译好的.exe程序是文件,而这个文件在编译好后是在磁盘这个外设上的,所以cpu会要求你把程序加载到内存,从而实现交互。而这个操作是操作系统帮你完成的,会自动加载到内存上(预加载)。CPU不和外设直接打交道,和内存直接打交道。外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。所有外设有数据需要载入,只能载入到内存中,内存写出也一定是写到外设中。简单来说,就**是所有设备都只能直接和内存打交道,提高整机效率。**
- 总结:所以程序的运行必须要加载到内存,CPU执行的代码访问数据,只能从内存中读取(这也是体系结构规定的)。
在这里大多数人还有一个问题就是,先将输入设备的数据交给内存,再由内存将数据交给CPU,这个过程真的比CPU直接从输入设备获取数据更快吗?
说明这个问题之前,我们首先需要知道:内存具有数据存储的能力。虽然内存的大小只有4G/8G,但是既然内存有大小,那么它就有预装数据的能力,而这就是提高该体系结构效率的秘诀。
这里不得不说到的就是局部性原理:根据统计学原理,当一个数据正在被访问时,那么下一次有很大可能会访问其周围的数据。所以当CPU需要获取某一行数据时,内存可以将该行数据之后的数据一同加载进来,而CPU处理数据和内存加载数据是可以同时进行的,这样下次CPU就可以直接从内存当中获取数据。
输出数据的时候也一样,CPU处理完数据后直接将数据放到内存当中,当输出设备需要时再在内存当中获取即可,这也就有了我们平常所说的缓冲区的概念。例如,缓冲区满了才将数据打印到屏幕上,使用fflush函数将缓冲区当中的数据直接输出之类的,都是将内存当中的数据直接拿到输出设备当中进行显示输出。
按理说,计算机把要处理的数据通过输入设备交给CPU处理,处理好后再通过输出设备显示结果,整个过程为何要有内存呢?
下面将从两个角度去解决这个问题:
一、技术角度:
CPU的内部是有寄存器的,寄存器就是一些存储单元,寄存器的速度是非常快的,而我们要清楚cpu的运算速度 > 寄存器的速度 > L1 ~ L3Cache > 内存 > 外设(磁盘)> 光盘磁带,因此我们得知输入输出设备的速度相较于CPU是很慢的,而如若直接把数据通过输入设备交给CPU处理,处理好后再通过输出设备显示结果,就会产生一个木桶效应:
因此得知,计算机体系的效率不是由cpu决定的(尽管cpu很快),而是由输入输出这两个外设决定的,这就导致计算机的效率非常的差,所以不能只把外设和cpu对接起来,这样的效率太低了。因此冯诺依曼就在输入输出和cpu之间添加了存储器来改变这一现状。
从数据角度看,外设不和CPU直接交互,而是和内存交互,CPU也是如此。仅是添加存储器这个媒介就能解决效率低的原因是如下:
1、从硬件上,存储器的存在更好的适配了外设和CPU速度不均衡的特点。
2、因为存储器的存在,让软件的存在有了更大的生存空间和价值。
- **总结:**内存在我们看来,就是体系结构的一个大的缓存,用于适配外设和CPU速度不均的问题!
二、成本角度
- 前面提到过,CPU具有寄存器,而寄存器也具有存储数据的能力,为什么不用CPU的寄存器来充当这个内存呢,这样就不再需要单独添加内存了。从技术上谈是可以的,但是这就要考虑到成本了:寄存器的成本 >> 内存 >> 磁盘(外设)。如果用寄存器充当内存,光成本就要几十w,真承担不起。而计算机之所以能蔓延全球,主要是其具有便宜和有效的特点。因此使用内存是最优选,既适配了速度不均的问题,也经济实惠。
- **总结:**使用内存可以达到用较低的成本,来获得较高的性能的特点。
运算器:
计算机计算的种类有两种:算数计算(+、-、*、/……) + 逻辑计算(&&逻辑与、||逻辑或……)
控制器:
控制器也是一个硬件,虽然外设和中央处理器在数据上没有交互,但并不代表它俩就没有交互。前面得知输入设备会把数据预装载到内存,从何和cpu进行交互,但是你怎么知道所有数据都被预装载了呢,针对没被预装载的数据,中央处理器就要和外设进行交互协商,而这个操作就是由控制器完成的,从而将数据尽可能加载到内存,或把数据从内存加载到外设。
几乎所有的硬件,只能被动的完成某种功能,不能主动的完成某种功能,一般都是要配合软件完成的(OS操作系统+CPU)这里的CPU只能被动接受别人的指令和别人的数据,那么CPU必须先认识别人的指令(每个CPU被制作都有自己的指令集),才能执行别人的指令,起到计算别人数据的目的。
上面说到CPU的速度很快,而外设的速度很慢,那么CPU直接从外设拿数据效率就降低了,所以数据是从外设加载到内存中的,然后CPU再从内存中读取数据,CPU处理完的数据再返回给内存(产生了缓存),数据再从内存中加载到外设,这大大提高的数据的处理。
所以CPU再读取和写入时候,在数据层面只和内存打交道,为了整体效率。内存从外设读取和写入数据的过程成为I/O过程(input/output)
借助计算机的输入设备,用户能够轻松地将数据或者指令传递给计算机。同时,计算机中的 CPU 会接收用户输入的指令或数据,并对其进行处理、加工,最终将处理结果反馈给用户。
下面给大家列举了一些常见的输入设备,如下表所示。
描 述 | |
---|---|
键盘 | 最常见的输入设备之一,其包含有多个按键,每个按键上都标有不同的数字、字母、字符等。 如今的键盘,可以通过 USB 或者蓝牙设备连接到计算机,用户只需要按压按键即可向计算机传递数据。 |
鼠标 | 一种手持输入设备,通常有 2 个按钮和一个滚轮组成。 借助鼠标,用户可以控制计算机屏幕上光标的移动,也可以选中某个应用程序并对其做打开、删除等操作。 |
扫描仪 | 用于扫描图片或者文档,并将扫描的内容转换为数字格式的数据传递给计算机。 |
摄像头 | 可以连接到计算机的任何摄像头,都可以称为网络摄像头,笔记本上的内嵌摄像头也可归为此类。 网络摄像头可以拍摄图像或者录制视频,然后将其转换为数字形式传输给计算机。 |
麦克风 | 麦克风是用于向计算机中输入声音的输入设备,它可以接收声音产生的振动信息并将其转换为音频信息,必要时它还可以将音频信息转换为数字形式供计算机存储。 |
数码相机 | 它可以捕捉图像、视频等信息,并以数字形式存储在存储卡中,用户也可以将存储的信息导入到计算机。 |
游戏杆/游戏方向盘 | 游戏杆的功能和鼠标类似,是一种确定位置的输入设备。和鼠标不同,游戏杆是通过摇杆的移动来改变计算机屏幕上光标的位置。 游戏方向盘常用作赛车游戏中的输入设备,借助该设备,用户可以在赛车游戏中控制赛车左转或右转。 |
触摸屏/触摸板 | 触摸屏和触摸板都可以看做是鼠标的替代品,它们都是输入设备。这 2 种输入设备允许用户通过手指控制计算机屏幕上光标的移动,还附带点击、选中某个应用程序等功能。 |
遥控器 | 遥控器允许用户在不离开座位的情况也可以控制某台设备。以电视遥控器为例,它可以调台、增大或减小电视机的音量等。 |
VR设备 | VR 是指由计算机生成的人工虚拟环境,用户借助 VR 设备(例如 VR 耳机、VR 眼镜等)即可与虚拟环境中的虚拟对象实现交互。 |
手势识别装置 | 此类输入设备可以识别人的手势,不同的手势会被识别为不同的指令传输给计算机。 |
生物识别设备 | 生物识别主要指的是通过指纹、眼角膜、面部结构等识别一个人的过程。 生物识别设备通常先扫描用户的信息,然后和存储在计算机(数据库)中的数据比对,从而判定该用户的身份是否符合要求。 |
光学字符阅读器(OCR) | 该输入设备可以扫描手写或者打印的文本信息,并将扫描到的数据转换为数字格式传输给计算机。 |
条形码阅读器 | 这是一种可读取条形码数据的输入设备。条形码阅读器可以扫描条形码表示的信息并传输给相连接的计算机。 |
读卡器 | 读卡器常用于读取银行卡,它可以将银行卡包含的信息传输给连接的计算机。 |
除上表列举的这些输入设备外,还有一些输入设备,例如 OMR 光标阅读器,数字化仪等,由于不太常见,这里不再做详细的介绍,感兴趣的读者可自行查阅相关资料。
计算机的输出设备用于向用户显示计算机对输入数据的处理结果。
计算机可以用多种多样的形式将处理结果展示给用户,比如文本、图像、音频以及视频等。
接下来给大家列举了一些实际生活中常用的输出设备,以及它们各自的特点。
显示器
显示器又称屏幕,是实际生活中最常用的输出设备之一。
显示器用于向用户显示经计算机处理后的数据,且支持文本、图像、音频、视频等多种显示形式。随着科技的不断进步,根据内部实现机制的不同,显示器又可细分为 CRT显示器(阴极射线管显示器)、LCD 液晶显示器、LED 显示器以及等离子显示器。
打印机
打印机的功能是将计算机的处理结果打印到纸张上,其显示形式可以为文本、图像等形式。
现今市面上的打印机,根据工作原理的不同大体可分为 2 类,分别为击打式打印机和非击打式打印,每一类还有更细致的划分,比如现在常用的喷墨式打印机、激光打印机都属于非击打式打印机,而针式打印机则属于击打式打印机。
投影仪
投影仪也是一种输出设备,它可以将计算机的处理结果以投影的方式显示到大屏幕或者墙壁上。
鉴于投影仪在显示计算机处理结果的同时,还能将其放大显示,因此该类输出设备常常用于演示或者教学。音箱
音箱也是一种输出设备,它可以将计算机的处理结果以音频的方式播放出来。
我们经常说CPU当中有寄存器,实际上寄存器不仅在CPU中,在其它外设中也有寄存器。
如:当我们敲击键盘时,键盘是先将获取到的内容存储在寄存器当中,然后通过寄存器将数据写入内存中。
在物理层面,各个硬件单元之间是通过总线连接的,外设与内存之间的总线叫做IO总线,内存与CPU之间的总线叫做系统总线。
在早些年的计算机中,因为芯片能力不强,有时是之间将外设中的数据传输给CPU,CPU计算完后在交给内存,在合适的时候由内存拿出数据。现在不在使用这个技术,而是在外设中使用DMA芯片,将外设的数据存入内存,不在利用CPU。
在数据层面上,CPU不和外设交互,但有时候,有些控制信号需要二者交互。如:一些外设给CPU发送控制信号,请求帮助处理一些数据。
我们已经有了对冯诺依曼体系的理解,接下来我们就可以看一下,在硬件层面,单机和跨主机之间,数据流是如何流向的!
也就是研究,我们将我们的程序加载到内存,然后执行我们的代码,最后在外设显示器上打印,它的整个数据流在硬件上是如何走的。
该内容难度不高,作为理解软件的工具。因为软件是无法脱离硬件的,当我们理解了硬件的数据流向,软件上的很多行为我们就可以尝试去理解它了。
我们以QQ音乐的启动来了解单机中数据是如何流动的?
以在音乐播放器(网易云音乐)播放音乐为例:
首先,我们的客户端软件,先加载到内存,然后由CPU执行,接着我们就看到了网易云的界面,其次,我们点击播放音乐,通过外设的网卡,拿到数据,再将数据传输到内存,经CPU计算(此时的计算可以看作解析),计算后将计算结果返回到内存,由内存传到外设,传到计算机的音箱中播放出来。
假设你和你的朋友进行qq聊天,如何解释一个数据从你的输入到输出的整个数据流动过程呢?
要使用QQ,首先需要联网,而A和B的电脑都是冯诺依曼体系结构,在A向B发送消息的过程中,A电脑中的键盘充当输入设备、显示器和网卡是输出设备。B电脑中的网卡充当输入设备、显示器充是输出设备。
因为你和你朋友的计算机都是冯诺依曼体系,所以你们通信的本质就是从一个体系结构到另一个体系结构,A在键盘上输入数据,在硬件上讲,将数据输入到内存,在软件上讲,将数据输入到QQ中。然后数据要经过计算和加密,经由CPU计算,将计算结果传回内存,由内存传到外设,这里是传到了两个地方,一个是A自己的显示器,因为他输入的消息,他自己也要看到,另一个传到了网卡,经由网卡传给B。B的计算机通过网卡拿到数据,将数据传给内存,经过CPU进行解密操作,在传回内存,由内存传到外设中的显示器,使B看到该消息。
其中,将外设中的数据读入内存,将数据显示在显示器上和发送到网卡,都是由软件(QQ)内部自己来完成。
对冯诺依曼的理解,不能停留在概念上,要深入到对软件数据流理解上,请解释,从你登录上qq开始和某位朋友聊天开始,数据的流动过程。 从你打开窗口,开始给他发消息,到他的到消息之后的数据流动过程。如果是在qq上发送文件呢?
- 发送消息 ——> 接受消息的数据流动:你的电脑键盘 —> 你的电脑内存 —> 你的电脑的CPU (加密) —> 你的电脑网卡 —> 你朋友电脑的网卡 —> 你朋友电脑的内存 —> 你朋友电脑的CPU (解密) —> 你朋友电脑的显示器
- 发送文件 ——> 接受文件的数据流动:你的电脑键盘 —> 你的电脑内存 —> 你的电脑的CPU (加密) —> 你的电脑网卡 —> 你朋友电脑的网卡 —> 你朋友电脑的内存 —> 你朋友电脑的CPU (解密) —> 你朋友电脑的显示器
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
- 内核(进程管理,内存管理,文件管理,驱动管理)
- 其他程序(例如函数库, shell程序等等)
在整个计算机软硬件架构中,操作系统的定位是: 一款纯正的“搞管理”的软件。对下要管理好软硬件资源,对上要给用户提供一个良好的运行环境。那操作系统究竟管理些什么呢?操作系统主要进行以下四项管理:
内存管理:内存分配、内存共享、内存保护以及内存扩张等等。
驱动管理:对计算机设备驱动驱动程序的分类、更新、删除等操作。
文件管理:文件存储空间的管理、目录管理、文件操作管理以及文件保护等等。
进程管理:其工作主要是进程的调度。
下面我将从三个方面去理解管理:
一、管理者不需要与被管理者直接交互,依旧能够很好的将被管理者管理起来
我们以学校为例,学校的校长并没有直接与我们 (学生) 进行交互,但是他仍然能够很好的将我们管理起来。可能有的同学会说,我们并不是由校长来管理的,而是由辅导员来管理的。但是实际上,辅导员并不算一个管理者,他没有重大事宜的决策权。
拥有对重大事宜的决策权的人才是管理者,虽然日常与我们进行交互的入是辅导员,但是辅导员对我们并没有决策权,比如你是否能够升级、是否能够评优评先、是否会别学校开除等等重大事项。
二、管理的本质就是对数据的管理
先举个例子,每个高校都有校长、辅导员、学生这三类人。这里面有人是做决策,有人是做执行,当然这也就有了管理者与被管理者的身份,而管理的本质:不是对被管理对象进行直接管理,而是只要拿到被管理对象的所有的相关数据,我们对数据的管理,就可以体现对人的管理!!而拿到相关数据的人就称为执行者,我们画个简图示意:
而上述校长的角色就是操作系统,辅导员就是驱动,学生就是硬件。对于计算机来说,各种硬件对应的驱动就是所谓的执行者,比如网卡有网卡驱动,磁盘有磁盘驱动;操作系统从这些驱动获取硬件数据,然后通过对硬件的数据进行管理实现对硬件的管理。
- 综上管理的本质是对数据的管理,但是数据是有“多、少”的分别的。当数据量很大时该如何管理呢,下面就来讨论。
三、管理的理念就是先描述,再组织
- 对于校长来说,他想管理上千号学生本质就是在管理数据,但是数据量很大,可是每个学生的重复数据类型很多,比如每个学生都具有籍贯、姓名、各科成绩……,我们先前在学习c语言的过程中,都知道有struct,它是用来描述对象的某种功能,如下:
struct student { 学生的基本信息(身高、姓名、年纪、电话……) 在校基本信息(宿舍号、专业、班级、年纪……) 考试成绩(高数、大物、英语……) 学校活动(学生会主席?班长?……) …… }; int main() { struct student zhangsan = { …… }; struct student lisi = { …… }; }
- 这是站在C语言的视角用结构体类型来定义变量,如果数据量过大,多大上万个,那么就要定义上万个变量来记录这些人的数据,可这就会导致这么多变量毫无关联,同样对于校长来说难道我要一个一个小本本的添加信息吗,这不纯纯冤种。对于校长,他就想到可以创建一个链表结构,在结构体内部构建前驱和后继指针
struct student { //学生…… struct student* next; struct student* prev; };
- 通过这样一个链表结构,每个节点存储了各个学生的相关信息,而这些节点又是前后相串联起来的,如图示:
- 此时对学生的管理,就变成了对链表的增删改查。校长要想派出一名学生去参加数学竞赛,那么就遍历此链表,并找出数学成绩最好的那个……
由硬件各种数据抽象出来的结构体
typedef struct device { int type; //设备类型 int status; //设备状态 ... //其他属性信息 struct device* next; //下一个设备的地址 }Dev;
对各种设备的数据进行管理转变为了对链表进行增删查改
list dev_list; struct Dev disk_div; dev_list.insert(disk_div); struct Dev keyBoard_div; dev_list.insert(keyBoard_div); dev_list.erase(display_div); ...
总结:管理的本质是对数据进行管理,而对数据的管理就是对某种数据结构的管理。管理的核心理念就是先描述、再组织。所以无论是C还是C++,都是来帮助我们描述对象的,而数据结构是帮助我们把所有的对象组织管理起来的。
先来看下银行的体系结构:
- 银行有自己的底层硬件,比如电脑,桌椅,仓库,宿舍……。当然上面也有一批人专门负责对应硬件的管理,这一批人直接和硬件打交道。再往上就会有银行的正式职工,可以用电脑,做桌椅,取钱,住宿舍……。因为这些职工的存在再往上就会产生银行的业务。而这些职工也会有人管理,叫做行长,可以管理软硬件。整个这一套就是银行的体系结构。
类似的操作系统也是差不多这个结构。
- 计算机的底层有相应的硬件和驱动程序,操作系统内核对下可以管理好软硬件,同样也要管理进程。并且可以对外提供服务。
- 操作系统并不相信任何的用户,它不会将自己任何的数据结构、代码逻辑……直接暴露给用户,为的是防止用户恶意修改操作系统,所以操作系统是通过系统调用的方式,对外提供接口服务!类似于银行的工作人员提供一个一个小的窗口来给我们服务。Linux操作系统是用C语言写的,这里所谓的“接口”,本质就是C函数!。我们学习系统编程,本质就是在学习这里的系统接口。
- 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库(用户操作接口),有了库,就很有利于更上层用户或者开发者进行二次开发。
既然操作系统是管理各种软硬件资源的软件,那么我们能否通过操作系统直接对各种软硬件进行操作呢?比如磁盘、显示器、磁盘驱动等设备;答案是不能,因为操作系统不相信任何用户,操作系统不确定我们是否会对各种软硬件进行违法操作,比如删除磁盘驱动、向磁盘中添加恶意数据等等。
但是操作系统又必须给上层用户提供各种服务,比如用户访问软硬件的需求,比如从磁盘中读取与写入数据、向显示器打印数据、通过网卡发送数据等等;针对上述情况,操作系统想了一个完美的方法:给用户提供系统调用的接口,即当用户有访问软硬件的需求时,直接调用操作系统提供的接口,然后由操作系统来帮助用户完成对应的工作;这样即满足了用户的需求,又保护了软硬件资源。
注:Linux 操作系统是托瓦兹大神于1991年使用C语言编写的,而上述的各种系统调用接口又是由操作系统提供的,所以它们也是C式的接口,说白了就是 用C语言编写的用于用户调用的各种函数接口。
虽然操作系统为我们提供了各种系统调用接口让我们来访问软硬件,但是这些接口在使用上功能比较基础,对用户的要求也相对较高;于是人们在系统调用接口的基础上开发出了用户操作接口,比如 Linux 下的外壳程序 shell,各种函数库 (C/C++等),windows 图形化界面 (GUI),以及一些指令 (编译好的可执行程序) 等;
用户通过这些操作接口进行指令操作、开发操作以及管理操作等等;比如 Linux 下外壳程序 bash 提供的 ls,本质上是调用系统接口,将磁盘中文件信息写入到显示器;touch 本质是调用系统接口,在磁盘上创建文件;又比如 C语言的 scanf/printf 函数,底层都是调用系统调用接口从键盘读入数据/向显示器上打印数据。
参考文章:
1、计算机软硬件体系结构
2、I/O设备(输入设备和输出设备)