冯 • 诺依曼体系结构

简介: 后经过内存与CPU的处理返回到显示器,就完成了一次信息的聊天。然后在网络当中经过一系列处理(这里忽略网络处理细节),之后你朋友的网卡从网络当中获取到你所发的消息后,将该消息加载到内存当中,你朋友的CPU再从内存当中获取消息并对消息进行解包操作,然后将解包好的消息写回内存,最后你朋友的显示器从内存当中获取消息并显示在他的电脑上。对,你的思考是正确的,但是理解是有点问题的,其实一个程序运行时必须将其相应的各种数据全都加载出来,加载的地方就为内存,加载出来后,如果要进行操作与修改,这时候CPU就开始工作了。


目录

image.png

冯•诺依曼体系结构由来的推导
虽然说冯 • 诺依曼体系结构是现代计算机系统的基础架构模型之一,它定义了计算机如何处理数据和执行指令。这个架构由约翰·冯·诺依曼在20世纪40年代提出,并成为计算机设计的标准模式。

但最初一开始时并不是这样设计的,其演变的过程这里就不再提及了,那么就直接拿我们所学习的冯 • 诺依曼体系结构来说明为什么这样设定。

首先明确知道的一点,计算机的产生就是为了解决人类难以解决的问题而产生的,比如说一些特别难以计算的数,那么想要通过计算机计算出答案,那么一定要存在输入设备与计算该数据的部分以及最后的输出设备。然而我们把计算数据的部分称为:算术运算和逻辑运算。计算机通过输入设备得到数据,数据在计算机当中进行一系列的算术运算和逻辑运算后,通过输出设备进行输出,于是就得到了以下流程图。

但是计算机当中只有算术运算功能和逻辑运算功能是不够的,还需要有控制功能,控制何时从输入设备读取想要的数据,何时输出数据到输出设备等。对应到C语言当中,算术运算就完成一系列的加减乘除的运算,而逻辑运算就对应于一系列的逻辑与逻辑或等,控制功能就对应于C语言当中的判断、循环以及各个函数之间的跳转等等。

而我们后人就将这个具有算术运算功能、逻辑运算功能以及控制功能的这个模块称为中央处理器,简称CPU。

但是实际上,输入设备与输出设备相对于CPU来说时非常的慢,于是在设计上这个体系虽然看似很合理,但是在呈现出的结果就是中间的操作特别快,两边的特别慢。根据木桶原理,那么最终整个体系所呈现出来的速度将会是很慢的。

所以当前这个体系结构显然是不合适的,于是我们就不让输入设备和输出设备直接与CPU进行交互,而在这中间加入了内存。

内存有一个特点,那就是其读取与输入数据的效率比输入设备与输出设备来说是快的很多很多,但这个快的程度又比CPU慢,所以内存是一个不慢不快的设备,能够在该体系结构当中就起到一个缓冲的作用。从而利用特殊设定使得整个体系的速度快很多。

现在该体系的运行流程就是:用户输入的数据先放到内存当中,CPU读取数据的时候就直接从内存当中读取,CPU处理完数据后又写回内存当中,然后内存再将数据输出到输出设备当中,最后由输出设备进行输出显示。
于是就形成了最终的冯诺依曼体系结构。

内存提高冯•诺依曼体系结构效率的特殊设定
其实在一开始学习冯 • 诺依曼体系结构,在得知其,先将输入设备的数据交给内存,再由内存将数据交给CPU,这个过程真的比CPU直接从输入设备获取数据更快吗?

在理论上来说就算在中间加好几个内存,输入设备,输出设备的速度慢,根据木桶原理,那他整体的速度该慢还是应该慢啊,不会提升多少啊。

是的,你没有理解错,如果不做特殊设定,只是在中间加上一个内存,其整体还是慢的。

但是,我们首先需要知道:内存具有数据存储的能力。虽然内存的大小只有4G/8G/16G/32G,但是既然内存有大小,那么它就有预装数据的能力,而这就是提高该体系结构效率的秘诀。

在这里,我们不得不提到局部性原理。根据统计学原理,当某一数据正在被访问时,下一次访问的概率较大可能会集中在该数据附近的其他数据上。基于这一规律,当CPU需要访问某一行数据时,内存通常会预先将该行数据及其周围的数据一起加载到内存中。这样,CPU在处理数据的同时,内存也在进行数据预加载,从而提高了效率。在下一次需要访问这些数据时,CPU可以直接从内存中获取,而无需再次访问较慢的存储设备。这种机制显著加速了数据的访问速度,并提升了系统的整体性能。
并且当CPU需要获取某一行数据时,内存可以将该行数据之后的数据一同加载进来,而CPU处理数据和内存加载数据是可以同时进行的,下次CPU就可以直接从内存当中获取数据。
在数据输出的过程中,CPU处理完数据后,通常将数据先存放到内存中,而不是立即发送到输出设备。当输出设备需要数据时,才会从内存中获取。这就引入了“缓冲区”的概念。举个例子,当你在编辑文档时,键入的文字并不会立即显示在屏幕上,而是暂时存储在内存中的缓冲区。只有当缓冲区中的数据达到一定量,或程序主动触发刷新时,才会一次性显示在屏幕上。

你用QQ和朋友聊天时数据的流动过程
在使用QQ前,我们都是先要联网的,你与你的朋友的电脑都是遵从冯 • 诺依曼体系结构,你要问为什么是这样,那就是因为要遵从冯 • 诺依曼体系结构,对的你没有听错,就是因为要遵从冯 • 诺依曼体系结构从而这样设定。

在你与你朋友聊天时,你先从你的输入设备键盘输入到内存经过CPU处理后返回到内存,后返回到输出设备,后经过网络传输到你朋友的输入设备网卡。后经过内存与CPU的处理返回到显示器,就完成了一次信息的聊天。这是简单的来说整个过程。在这个过程中你的电脑中键盘就为输入设备,你的显示器与网卡就为输出设备,你朋友的电脑中的网卡就为输入设备,显示器就为输出设备。

刚开始你在键盘当中输入消息,键盘将消息加载到内存,此时你的显示器就可以从内存获取消息进而显示在你自己的显示器上,此时你就能在你自己的电脑上看到你所发的消息了。

在你的输入设备键盘将数据加载到内存时,你的电脑就已经与通过网卡与网络建立联系,及已经可以从内存中读取相应的信息。然后在网络当中经过一系列处理(这里忽略网络处理细节),之后你朋友的网卡从网络当中获取到你所发的消息后,将该消息加载到内存当中,你朋友的CPU再从内存当中获取消息并对消息进行解包操作,然后将解包好的消息写回内存,最后你朋友的显示器从内存当中获取消息并显示在他的电脑上。

与冯•诺依曼体系结构相关的一些知识
寄存器
一个典型的CPU由运算器、控制器、寄存器等器件构成,分工如下:

对于汇编程序员来说,CPU中的主要部件是寄存器,寄存器是CPU中程序员可以用指令读写的部件,程序员通过改变各种寄存器中的内容来实现对CPU的控制。不同CPU,寄存器个数、结构是不同的。

但是我们经常说CPU当中有寄存器,实际上寄存器不仅仅在CPU当中存在,在其他外设当中也是有寄存器的。例如,当我们敲击键盘时,键盘是先将获取到的内容存储在寄存器当中,然后再通过寄存器将数据写入内存当中。

32位通用寄存器有八个,eax, ebx, ecx, edx, esi, edi, ebp, esp,

扩展:寄存器作为硬件,其造价特别的高。对于一般的民用电脑寄存器的数量特别少,但是对于一些特别贵的电脑,其贵的地方主要就是寄存器。

预加载到内存
根据冯诺依曼体系结构图,我们可以知道,站在硬件角度或是数据层面上,CPU只和内存打交道,外设也只和内存打交道。到这里我们也可以说明一个问题:为什么程序运行之前必须先加载到内存?
因为可执行程序(文件)是在硬盘(外设)上的,而CPU只能从内存当中获取数据,所以必须先将硬盘上的数据加载到内存,也就是必须先将程序加载到内存。

那你要这么说,我就有点不理解了,我们在windows下想要运行一个.exe的程序,我一个双击就点开他正常运行了啊,我也没有明确体现到他又先把程序加载到内存啊,他是这里运行了啊。

对,你的思考是正确的,但是理解是有点问题的,其实一个程序运行时必须将其相应的各种数据全都加载出来,加载的地方就为内存,加载出来后,如果要进行操作与修改,这时候CPU就开始工作了。

在比如说:

映像加载:Windows会将可执行文件的内容(包括程序代码、静态数据和动态链接库等)从硬盘读入内存。
内存分配:操作系统会为程序分配适当的内存空间,并将程序的各个部分(代码段、数据段等)加载到对应的内存区域。
动态链接库(DLL)的加载:如果程序依赖于某些动态链接库(例如 kernel32.dll、user32.dll 等),Windows会在程序启动时将这些库加载到内存中。

常见的输入设备和输出设备(拓展):
 输入设备:键盘、鼠标、网卡、硬盘、话筒、摄像头、扫描仪等。
 输出设备:显示器、音响、网卡、硬盘、打印机等。
注意: 同种设备在不同场景下可能属于输入设备,也可能属于输入设备。

在物理层面上,各个硬件单元之间是通过总线连接的,外设与内存之间的总线叫做IO总线,内存与CPU之间的总线叫做系统总线。

目录
相关文章
|
6月前
|
存储 DataX C语言
vector与list的简单介绍
vector是表示大小可以变化的数组的序列容器。就像数组一样,vector对其元素使用连续的存储位置,这意味着也可以使用指向其元素的常规指针上的偏移量来访问其元素,并且与数组中的元素一样高效。但与数组不同的是,它们的大小可以动态变化,它们的存储由容器自动处理。在内部,vector使用动态分配的数组来存储其元素。当插入新元素时,可能需要重新分配此数组才能增大大小,这意味着分配一个新数组并将所有元素移动到该数组。
272 0
vector与list的简单介绍
|
6月前
|
Linux 编译器 vr&ar
Linux的动态库与静态库
静态库在编译时直接嵌入到最终的可执行文件中。
150 0
|
6月前
|
存储 安全 Java
c++--继承
c++作为面向对象的语言三大特点其中之一就是继承,那么继承到底有何奥妙呢?继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用,继承就是类方法的复用。
144 0
|
6月前
|
Linux 网络安全 开发工具
在Linux下配置gitee与Github的远程仓库
注意,git push后,是输入你的账号与密码。这个步骤可以通过特殊设置省去,但是一开始还是不要太省。
327 0
|
6月前
|
存储 人工智能 Unix
Linux常见指令汇总
最常见的就是 ll (为ls -l的省略)
211 0
|
6月前
|
C语言 C++
c与c++的内存管理
再比如还有这样的分组: 这种分组是最正确的给出内存四个分区名字:栈区、堆区、全局区(俗话也叫静态变量区)、代码区(也叫代码段)(代码段又分很多种,比如常量区)当然也会看到别的定义如:两者都正确,记那个都选,我选择的是第一个。再比如还有这样的分组: 这种分组是最正确的答案分别是 C C C A A A A A D A B。
113 1
|
6月前
|
Linux C语言 网络架构
Linux的基础IO内容补充-FILE
而当我们将运行结果重定向到log.txt文件时,数据的刷新策略就变为了全缓冲,此时我们使用printf和fwrite函数打印的数据都打印到了C语言自带的缓冲区当中,之后当我们使用fork函数创建子进程时,由于进程间具有独立性,而之后当父进程或是子进程对要刷新缓冲区内容时,本质就是对父子进程共享的数据进行了修改,此时就需要对数据进行写时拷贝,至此缓冲区当中的数据就变成了两份,一份父进程的,一份子进程的,所以重定向到log.txt文件当中printf和fwrite函数打印的数据就有两份。此时我们就可以知道,
103 0
|
6月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
75 0
|
6月前
|
Linux 调度 C语言
Linux进程概念-详细版(一)
子进程与父进程代码共享,其子进程直接用父进程的代码,其自己本身无代码,所以子进程无法改动代码,平时所说的修改是修改的数据。为什么要创建子进程:为了让其父子进程执行不同的代码块。子进程的数据相对于父进程是会进行写时拷贝(COW)。
165 0
|
6月前
|
监控 Shell Linux
Linux进程控制(详细讲解)
进程等待是系统通过调用特定的接口(如waitwaitpid)来实现的。来进行对子进程状态检测与回收的功能。
125 0