本人才疏学浅,如果我的内容有明显的错误,或者有疑问的地方,衷心希望您能和我联系,给出建议和指导,或者与我交流相关知识。我会对你表示无限的感激!欢迎指正!
老师上周单独布置给我的任务:让我去搞清楚“一条指令在cpu里是如何执行的呢?”。然后可以画张图第二节课讲给同学们。
回去后,我想这首先得去搞清楚CPU的原理,对于我这个所谓的计算机相关专业的学生,我们专业根本没开计算机组成原理这节课!!!(5555555)一时间我真的是懵逼上加懵逼。。。
在通过查阅资料,刷B站搬运的视频(国外的印度小伙搞这些教程确实挺厉害的,我都竟然能听懂)。直接开讲吧,组织组织语言,过几天就要上台介绍了…
其实这个问题我感觉问的有的宽泛,如果直接从原理开讲,这直接就是《计组》开课了,一下子根本讲不完,况且我学术浅薄,能达到像老师一样去讲课,去“传道授业解惑”的高度,还挺遥远。。。
-----------------分割线------------------
我想,我们目前在上Linux课程,倒不如把问题具体化一丢丢,即“Linux系统中,一条指令在CPU里是如何执行的?”,从这里切入,我们去看看CPU大概是怎么工作的,我相信对CPU的原理和标题的问题都有了答案。
好的,看图,相信我们对除了CPU这一块简单的流程比较眼熟吧(当时冯老师让我们都画一画Shell解析命令的步骤图),这一次,我就从我们都熟悉的命令来走一走这个流程,“mkdir jd”!!!
首先,我有一个问题想问大家:你看到这个题目的时候,你会不会和我一样觉得,诶,"mkdir jd"这不就是一条指令吗?对,也不对,还是得区分一下!在Linux中,你可以叫这条命令也可以叫这条指令,它只是我们人类在操作系统的命令行中指示计算机执行操作的文本字符串! 随你怎么叫它。
这和CPU中的指令一定要区别开来,我们计算机领域说指令的话,一般都是指CPU有关的指令!它是cpu的处理数据的基本单位!!!(划重点,会考!!)它用于告诉 CPU 完成特定的操作或任务,这些指令可以执行各种不同的任务。
输入命令后,Shell解释器首先对该命令进行解析,并调用相应的系统调用(mkdir),进而向内核发送请求,内核接收到请求后,(也向CPU去发起请求,得到管理这些资源的权限等)在内存中创建进程,并为该进程分配内存空间;设置PC值,这个PC值待会会在CPU里提到,这两个PC不是一个东西,但有联系(内存中的PC可以看作是CPU和内存之间的一个通信标记。在程序执行期间,内存中的PC和CPU中的PC会不断地交换和更新信息,以保持CPU和内存之间的同步。以确保下一次CPU从正确无误的地址读取指令。);加载指令,即内核在磁盘中搜索到有可执行程序(/bin/mkdir),然后把它加载到内存中。
注意这里得了解一下指令、指令集和程序之间的联系, 我们可以这么理解:这个可执行程序里呢,就有大量的指令集,指令集呢,又由一个一个有序的指令组成。这里又得注意这是可执行程序,即它们在加载前就已经被程序员们设计和编译好的,大量的0和1组成的指令,这种已经编译好的指令我们称为机器指令,组成的指令集称为机器指令集(没有编译好的,也就是我们人类可读的源代码)。
那好,/bin/mkdir程序的机器指令集已经在内存中有序加载了,即每个指令对应一个地址(这个地址很重要),如图,比如说这几个函数就是/bin/mkdir这个程序执行中需要系统调用的。此时认真听的同学应该会有疑问,诶,那你刚刚不是说机器指令集都是编译好的,即都是大量的01组成,你这里画的欠妥。是的,你说的没错,比如调用第一个函数,它可能是执行了数个指令(有兴趣的同学可以了解一下常见的指令,如Load加载啊、加减乘除啊,Jump跳转啊等等),正是这些小小的指令,一个一个的组成了我们的CPU可以处理的可执行的程序,所以因为本人的时间和画图空间有限,所以在这里需要你将图中的调用函数当作一个指令,注意是一个,然后我们开始看CPU内部是如何执行这个指令的?
这里的CPU有两个核心部件,一个控制器(CU),一个运算器(ALU),然后CPU中分布着一些有功能的寄存器(Reg),CPU与“外界”进行“交互”(数据传输啊,控制啊)就是通过总线(有地址总线、数据总线、控制总线这里就不多说了)。首先控制器中有一个叫指令计数器的部件,管它叫PC(Program Counter),它是一种特殊的寄存器,它存储着当前正在执行的指令的地址,通过地址总线将该地址发送到内存中。比如现在是0x00,代表着我要执行fork()这个指令,这时候指令寄存器(Instruction Register,IR)出场了,它从内存中读取这条指令并将其存储到指令寄存器中。这个过程呢就是我们说的取指(Fetch)!
接来呢,指令译码器出场了,它将刚刚拿到的指令(我把它比喻天书一堆010101嘛)转换为为相应的操作控制信号,即如图上说的具体运算(就是说原来这些0101是加或者减或者其他的具体运算操作,终于不是天书,能读懂了)。这个过程呢,就是我们说的译码(Decode)!
接下里,控制器将译码后的指令传给运算器(通过数据总线,多提一句,这些都是一个个的电子元件,它们都是由各种复杂的电路连通的),这些有着具体运算的指令在运算器中就可以进行它们各种各样的运算。这个过程呢,就是我们说的执行(Execute)!接下来需要注意的是,在大多数情况下,每执行一条指令后,PC 的值会自动增加,以指向下一条即将被执行的指令。这个过程被称为“PC 自动增加”。它会根据指令的长度自动增加 PC 的值,并将其设置为下一条要被执行的指令的地址。比如说这里当0x00执行完后,PC的值就增加到0x04(这里假设使用了32位的机器码来表示(取决于处理器),即每个指令长度为4个字节),即指向了下一条指令。
完成运算后,得到的结果,可能会暂时存储到寄存器中(因为这些结果需要在后续指令中进行使用),这里负责存储数据的寄存器我们把它叫做通用寄存器。并且可以通过寄存器之间的数据传输操作来进行合并和处理。这个过程我们把它叫做暂存!
在某些情况下,指令执行的结果可能需要存储到内存中以便长期保存。比如这个情况下,在执行mkdir命令时,内核需要在硬盘上创建一个新的目录来保存文件。此时,内核会将相应的信息存储到内存中,并通过特定的系统调用将这些信息写入硬盘。在将结果写入目标寄存器或内存中的过程呢,就是我们说的写回(write-back)!
那么到此整个流程就过完了。这就是我这张图呈现的相关内容。我本来是给这张图标号了顺序,想呈现一个流程式的流程图,但是后来想了想,这根本不能强行定序,CPU作为“大脑”,其实它无处不在,我这里是通过CPU与内存的“交互”来让大家明白CPU的原理和指令执行的基本步骤。其实你看Shell解释器啊,内核啊,它们在执行这些操作(指图上的操作)之前,其实都有与CPU进行请求等操作。所以说有关于CPU的学问还有更多且更深,我这里只是粗浅地表示出一些基础知识,比如说cpu流水线技术、指令还分操作码,操作数、CPU 的中断模式等等知识,你们感兴趣可以自己查阅资料,毕竟我的时间和精力有限,目前只能陈述这么多。
推荐一个视频,我觉得对于小白来说很不错,看完之后一定有收获,虽然是全英语,但有生动形象的动图和中文字幕。真心推荐!
【【科普】CPU的工作原理】https://www.bilibili.com/video/BV1R54y1k7Pr?vd_source=062a6b7b1a3a8082a74d48f1682bd018
本人才疏学浅,如果我的内容有明显的错误,或者有疑问的地方,衷心希望您能和我联系,给出建议和指导,或者交流相关知识。我会对你表示无限的感激!欢迎指正!
-----------------分割线------------------
今天向鹏子哥取经时(他今天面试),看到他在看“ssh开机启动流程”章节。当时的屏幕上出现了CPU相关字眼,我回到座位上后纳闷极了,心里想:啊??冯老师讲过吗?我之前把这个章节过了,一点印象没有,哎…我这个人就这样…学了就忘,好难受,什么时候才能有一定实力啊,现在找个工作感觉都辣么南/(ㄒoㄒ)/~~
后来我马上回看那个暑期集训章节,原来是魏红学姐的字节跳动面经里的题目,问了大量的CPU相关知识,今天我又跟着老师看了一遍,发现这些知识点在我脑袋里很顺畅的过去了,哇靠,这些问题如果放在之前看视频的我,那确实是一脸懵逼,经过这两天CPU的洗礼,我觉得面试官问的原理问题也不难啊,我甚至感觉还能从一些点切入能反问面试官,和面试官探讨(幻想中的hhhhh,要是正在现场了估计紧张的啥都忘了)。总之,我突然一下就明白的冯老师的用心良苦!!!很感激!觉得这些努力或许也不是白费的啊。来,让我们看看2022年秋招字节跳动一面的题目:
1.cpu的处理数据的基本单位
这不就是 指令嘛!Instruction!
2.cpu怎么工作的?简述cpu的工作原理
简述啊,我感觉这里我能跟你至少聊个半小时,把上面这些字全跟他聊了,而且我还有一堆问题可以反问,我天,想一想还有点酷啊。简述就简述吧,哎。
1.取指:CPU 通过地址总线向内存发送地址,将要执行的指令读入寄存器。
2.解码:CPU 将每条指令解密并翻译成具体操作。
3.执行:根据指令操作码,CPU 对数据进行运算、逻辑判断等操作。
4.暂存:得到的结果,可能会暂时存储到寄存器中。
5.写回:将结果写入目标寄存器或内存中
CPU 不断重复上述步骤,直到程序执行完毕。
然后还可以和面试官讲一下PC自动增加这个过程
——————简述大概到此就讲清楚咯
感兴趣的话,你还可以跟面试官多聊些,可以把一些难点问一问他。总可以吧?毕竟他提的问题我已经回答出来了,这是问题外扩展中的问题
在这个过程中,CPU 还需要处理来自外部设备的中断请求,以及与其他硬件组件之间的通信,如输入输出设备、存储器等。
CPU按照一定的流水线执行指令,即将一条指令的不同步骤分别交给不同的硬件模块完成,以提高指令的处理速度。由于各个模块之间存在时序关系,所以CPU需要根据指令类型和执行情况动态调整流水线的状态,保证指令能够正确无误地执行。
总的来说,CPU的工作原理非常复杂,需要高度协调和精密控制才能完成各种任务。
这两个题不就很轻松和有信心地拿下咯!大厂面试题不过如此嘛(菜菜,捞捞!!!)