冯 • 诺依曼体系结构
从此篇开始,就开始学习 Linux 系统部分 —— 进程,在正式学习 Linux 进程之前,我们需要铺垫一些概念,如冯诺依曼体系结构、操作系统的概念及定位、进程概念,我们会先铺垫理论,再验证理论。其次对于某些需要深入的概念我们只是先了解下。本文中的 fork 只会介绍基本使用,以及解答 fork 为啥会有 2 个返回值、为啥给子进程返回 0,而父进程返回子进程的 pid;而对于用于接收 fork 返回值的 ret 是怎么做到 ret == 0 && ret > 0、写时拷贝、代码是怎么做到共享的、数据是怎么做到各自私有的等问题会在《Linux进程控制》中进行展开。
一、冯 • 诺依曼体系结构
💦 体系结构
冯 • 诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。数学家冯 • 诺依曼提出了计算机制造的三个基本原则,即采用二进制逻辑
、程序存储执行
以及计算机由五个部分组成 (运算器、控制器、存储器、输入设备、输出设备)
,这套理论被称为冯 • 诺依曼体系结构。我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。其中:
- 输入设备:键盘、鼠标 … …。
- 输出设备:显示器、音响 … …。
- 存储器:如没有特殊说明一般是内存。
- 运算器:集成于 CPU,用于实现数据加工处理等功能的部件。
- 控制器:集成于 CPU,用于控制着整个 CPU 的工作。
各个组件之间的互通是通过 “ 线 ” 连接实现的,这可不是那种电线杆上的线,因为计算机更精密,所以使用 “ 主板 ” 来把它们关联在一起。
💦 数据流向
冯 • 诺依曼体系结构规定了硬件层面上的数据流向,所有的输入单元的数据必须先写到存储器中 (这里只是针对数据,不包含信号(通过外设直接对 CPU 交互)),然后 CPU 通过某种方式访问存储器,将数据读取到 CPU 内部,运算器进行运算,控制器进行控制,然后将结果写回到内存,最后将结果传输到输出设备中。
我们在 C/C++ 中说过,可执行程序运行时,必须加载到内存,为啥 ❓
在此之前先了解一下计算机的存储分级,其中寄存器离 CPU 最近,因为它本来就集成在 CPU 里;L1、L2、L3 是对应的三级缓存;主存通常指的是内存;本地存储(硬盘)和网络存储通常指的是外设。
如图所示,这样设计其实是因为造价的原因,对于绝大多数的消费者,你不可能说直接把内存整个 1 个 T 吧,当然,氪金玩家除外。
其中通过这个图,我们想解释的是为啥计算机非得把数据从外设(磁盘) ➡ 三级缓存(内存) ➡ CPU,而非从外设(磁盘) ➡ CPU。
原因是因为离 CPU 更近的,存储容量更小
、速度更快
、成本更高
;离 CPU 更远的,则相反。假设 CPU 直接访问磁盘,那么它的效率可太低了。这里有一个不太严谨的运算速度的数据,CPU 是纳秒级别的;内存是微秒级别的;磁盘是毫秒级别的。当一个快的设备和一个慢的设备一起协同时,最终的运算效率肯定是以慢的设备为主,就如 “ 木桶原理 ” —— 要去衡量木桶能装多少水,并不是由最高的木片决定的,而是由最短的木片决定的。也就是说一般 CPU 去计算时,它的短板就在磁盘上
,所以整个计算机体系的效率就一定会被磁盘拖累。所以我们必须在运行时把数据加载到内存中,然后 CPU 再计算,而在计算的期间可以同时让输入单元加载到内存,这样可以让加载的时间和计算的时间重合,以提升效率。
同理因为效率原因 CPU 也是不能直接访问输出单元的,这里以网卡为例,我刚发条 qq 消息给朋友,发现网络很卡,四五秒才发出去,而在这个过程,你不可能让 CPU 等你四五秒吧,那成本可太高了,所以通常 CPU 也是把数据写到内存里,合适的时候再把数据刷新到输出单元中。
所以本质上可以把内存看作 CPU 和所有外设之间的缓存
,也可以理解成这是内存的价值。
💨小结:所有数据 ➡ 外设 ➡ 内存 ➡ CPU ➡ 内存 ➡ 刷新到外设,其中 CPU 不直接和外设交互,外设只和内存交互。注意一定要区分清楚某些概念是属于 “ 商业化的概念 ” 还是 “ 技术的概念 ”。
💦 实例
对冯诺依曼的理解,不能只停留在概念上,要深入到对软件数据流理解上,请解释,你在qq 上发送了一句 “ 在吗 ” 给朋友,数据的流动过程 ?如果是在 qq 上发送文件呢 (注意这里的计算机都遵循冯 • 诺依曼体系结构,且这里不谈网络,不考虑细节,只谈数据流向) ?
☣ 消息:
☣ 文件:
本质上发消息和发文件是没有区别的。学习这里实例的意义是让我们在硬件层面上理解了它的数据流,你的软件无论是 QQ、WeChat 等都离不开这样的数据流。
- 点赞
- 收藏
- 关注作者
评论(0)