CPU如何执行代码行?


11

我试图真正理解高级语言如何准确地转换为机器代码,然后由cpu执行。

我知道该代码已编译为机器代码,这是CPU可以使用的低级代码。如果我有作业说明,请说:

x = x + 5;
y = x - 3;

CPU是否一次执行每一行?因此,它将首先执行x = x + 5; 指令,然后CPU将执行的下一条指令是y = x-3; 我实际上是想了解执行过程以及我编写的代码实际上是如何由CPU执行的。


您可能想尝试了解一种开源CPU的设计,其中有一些非常简单的基于堆栈的实现,例如excamera.com/sphinx/fpga-j1.html-它们比3地址体系结构简单得多。就像您的示例一样。
SK-logic

3
当我从事这项业务时,这将有简单且定义明确的答案。如今,CPU非常复杂,需要做各种事情来提高处理能力。
David Thornley,2012年

Answers:


12

这些代码行与CPU的执行方式无关。我建议您阅读汇编程序,因为这将教给您很多有关硬件实际如何执行操作的知识。您还可以从许多编译器获得汇编程序输出。

该代码可能会编译成以下形式(以一种汇编语言形式):

load R1, [x] ; meaning load the data stored at memory location x into register 1
add R1, 5
store [x], R1 ; store the modified value into the memory location x
sub R1, 3
store R1, [y]

但是,如果编译器知道不再使用变量,则可能不会发出存储操作。

现在,为了让调试器知道什么机器代码与程序源代码行相对应,编译器将添加注释以显示什么行与机器代码中的位置相对应。


为什么不?3地址体系结构将具有类似ADD Rx, Rx, $5和的指令SUB Ry, Rx, $3(假设x和y变量已映射到寄存器中)。您正在描述一种加载/存储RISC方法。
SK-logic

1
@ SK-logic:虽然这可能发生在具有数据类型和操作的非常简单的编程语言中的非常简单的代码行中,但CPU恰好能够很好地支持这种情况,但这不是一般情况。这对专家来说很方便,但是首先重要的是要认识到,机器语言指令通常在高级语言中几乎没有代码行的可重用性。

@ SK-Logic:仅适用于此特定示例。但是,总的来说,maxpolun是正确的。必须将高级语言语句翻译为较低级的语言,并需要更多的“繁文tape节”才能完成概念上简单的工作。我想OP正在要求这种转变的例子。
Andres F.

1
@ SK-Logic:OP提出了“我正在尝试真正理解高级语言的精确 ”的问题
Andres F.

1
@ SK-logic上下文是“如果我有一个赋值语句说:[代码段] CPU一次执行每一行吗?” -在我看来,它的目的是成为非汇编语言的源代码。更一般地说,我看不出有任何关于底层机器代码的理解的指示,并且某些措辞(例如谈论行)表明了一些误解。这并不是您所暗示的那样不可能,并不是每个人都喜欢首先被一些简单的微控制器(例如我,显然还有其他的微控制器)抛弃。也许弗兰基应该澄清一下。

2

这取决于。

是的,在真正简单的机器的早期,代码一次只能执行一行。随着机器变得更大,更快和更复杂,您开始看到同时执行多条指令的能力和内存读写操作所需的时间比对寄存器的操作要长得多。

优化编译器必须考虑到这一点,您给出的代码行可以“或多或少”并行执行,其中处理器的一部分用于计算y,而另一部分则存储先前计算的y值。 x(而y的计算使用的是寄存器中的新值)。

Control Data 6600是我所知道的第一台执行这种操作的机器。整数加法花费了300纳秒,内存引用(读或写)花费了1000纳秒,乘法和除法花费了很多时间。根据所需的功能单元,最多可以并行执行十条指令。CDC 6600 FORTRAN编译器非常擅长调度所有这些。


在这种情况下,下一条指令的输入取决于第一条指令的结果,因此必须 顺序执行。
SK-logic

@ SK-logic:不完全是。第二行的输入取决于第一行右侧的结果,但是,仅基于我们在原始示例代码中看到的内容,它可能不取决于将结果存储到内存中第一行。如果x已声明为volatile(在C / C ++中),那么在开始计算y的新值之前,将要求编译器先存储结果,然后从内存中重新加载它,因为“ volatile”表示某些东西(例如,一个中断处理程序)可能会进入,并在两行之间切换x。
约翰·斯特罗姆

我假设x和y是寄存器(并且代码使用3地址伪汇编语言而不是C)。在这种情况下,两个指令不可避免地是顺序的。否则,OP必须问两个或多个不同的问题,而不是这个问题。
SK-logic

我想知道处理器是否会尝试“推测”值x是什么?这样,它已经执行了代码并将其存储在缓存中。
Kolob峡谷

即使它们是寄存器,取决于机器,您也不能假定指令完全按顺序执行。6600具有调度逻辑(“记分板”),该逻辑基于程序员想要做的显而易见的假设而强制采用顺序语义。后来的机器省略了该硬件,而是依靠编译器仔细调度指令。在这些野兽上进行汇编语言编程的人类程序员是自己的。
约翰·R·斯特罗姆

1

不可以,高级语言和低级语言的代码行/指令之间没有一对一的映射。实际上,以上两行都被翻译成多个机器代码指令,例如

  1. 将某个存储器地址中的值加载到寄存器中
  2. 修改值
  3. 写回内存

这些说明的实际细节在平台之间有所不同。

这是事物的基本观点。但是,令问题进一步复杂化的是,现代CPU应用了诸如执行管道乱序执行多核等技术。这些导致CPU一次执行多项操作,例如,流水线在同一处理单元内并行处理后续指令的不同阶段,而多个内核可以并行处理独立的指令。


0

您应该在书中仔细阅读详细内容,以找到有关其工作方式的更多详细信息,可能还包括编译器类。

基本上,您的问题集中在2个不同方面。

1)代码如何转换为机器代码?

2)何时/如何使用并行化计算代码?

1)的答案取决于您使用的语言(尽管您的示例很简单,所以输出是相同的)。编译器翻译成机器代码的方式是语言的力量之一。此外,在您的示例中还需要考虑几个问题,代码应将数据加载到内存中,进行存储等。

最后,并行化是一种可以从编程角度考虑的功能,但是总而言之,某些处理器可能会认为某些代码部分可以同时运行,因为它们是独立的。很显然,情况并非如此,因为您需要按顺序执行语句,所以不会,它不会同时运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.