从微体系结构抽象的x86程序计数器? [英] x86 Program Counter abstracted from microarchitecture?

查看:186
本文介绍了从微体系结构抽象的x86程序计数器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 RISC-V Reader:开放式体系结构图集。作者在解释ISA(指令集体系结构)与特定实现(即微体系结构)的隔离时写道:

I'm reading the book The RISC-V Reader: An Open Architecture Atlas. The authors, to explain the isolation of an ISA (Instruction Set Architecture) from a particular implementation (i.e., microarchitecture) wrote:


对于架构师来说,诱惑在于将指令包含在ISA中,以帮助在特定时间实现一种实现的性能或成本,但会负担不同的或将来的实现。

The temptation for an architect is to include instructions in an ISA that helps performance or cost of one implementation at a particular time, but burden different or future implementations.

据我了解,它指出,在设计ISA时,ISA应该理想地避免公开实现它的特定微体系结构的细节。

As far as I understand, it states that when designing an ISA, the ISA should ideally refrain from exposing the details of a particular microarchitecture that implements it.

请牢记上面的引号:当涉及程序计数器时,在RISC-V ISA上,程序计数器( pc )指向当前正在执行的指令。另一方面,在x86 ISA上,程序计数器( eip )不包含当前正在执行的指令的地址,而是一个的地址。遵循当前指令

Keeping the quote above in mind: When it comes to the program counter, on the RISC-V ISA, the program counter (pc) points to the instruction being currently executed. On the other hand, on the x86 ISA, the program counter (eip) does not contain the address of the instruction being currently executed, but the address of the one following the current instruction.

x86程序计数器是否从微体系结构中抽象出来了?

Is the x86 Program Counter abstracted away from the microarchitecture?

推荐答案

我将用MIPS而不是x86来回答这个问题,因为(1)MIPS和x86在该领域有相似之处,并且(2)RISC V由Patterson开发等人在拥有数十年的MIPS经验之后。我觉得在比较中可以最好地理解他们书中的这些陈述,因为x86和MIPS都编码相对于指令末尾的分支偏移量(MIPS中为pc + 4)。

I'm going to answer this in terms of MIPS instead of x86, because (1) MIPS and x86 have a similarity in this area, and because (2) RISC V was developed by Patterson, et al, after decades of experience with MIPS.  I feel these statement from their books are best understood in this comparison because x86 and MIPS both encode branch offsets relative to the end of the instruction (pc+4 in MIPS).

在MIPS和x86中,相对于PC的寻址模式仅在早期ISA版本的分支中都可以找到。后来的修订版增加了PC相对地址的计算(例如MIPS auipc 或x86-64的LEA或加载/存储的RIP相对寻址模式)。这些都彼此一致:偏移量是相对于指令的末尾(即下一条指令的开始)(一个过去)编码的,而正如您所注意到的那样,在RISC V中,编码的分支偏移量(和auipc是

In both MIPS and x86, PC-relative addressing modes were only found in branches in early ISA versions. Later revisions added PC-relative address calculation (e.g. MIPS auipc or x86-64's RIP-relative addressing mode for LEA or load/store). These are all consistent with each other: the offset is encoded relative to (one past) the end of the instruction (i.e. the next instruction start) — whereas, as you're noting, in RISC V, the encoded branch offset (and auipc, etc..) is relative to the start of the instruction instead.

此值的含义是它从某些数据路径中删除了一个加法器,有时是其中的一个数据路径。可能在关键路径上,因此对于某些实现,数据路径的这种较小的缩短意味着更高的时钟速率。

The value of this is that it removes an adder from certain datapaths, and sometimes one of these datapaths can be on the critical path, so for some implementations this minor shortening of the datapath means a higher clock rate.

(当然,RISC V仍必须产生指令+ 4用于pc-next和调用指令的返回地址,但是在关键路径上要少得多。 注意,在下图中,两个都没有将pc + 4捕获为返回地址。)

(RISC V, of course, still has to produce instruction + 4 for pc-next and the return address of call instructions, but that is much less on the critical path.  Note that in the diagrams below neither shows the capture of pc+4 as a return address.)

让我们比较一下硬件框图:

Let's compare hardware block diagrams:



              nbsp; bsp                 nbsp;          &b




      ;              nbsp; b&bsp; nbsp; nsp ;               RISC V数据路径p>

                                               RISC V datapath (simplified)

您可以在RISC V数据路径图上看到标记为#5的线(红色,位于控制椭圆上方),绕过加法器( #4,为PC加4 pc-next)。

You can see on the RISC V datapath diagram the line tagged #5 (in red, just above the control oval), bypasses the adder (#4, which adds 4 to the pc for pc-next).

图表归因

  • MIPS: Need help in adding functionality to MIPS single cycle datapath?
  • RISC V: https://www.codementor.io/erikeidt/logic-block-diagrams-w6zxr6sp6

为什么x86 / MIPS在最初的版本中做出了不同的选择吗?

当然,我不能肯定地说。在我看来,可以做出选择,而且对于最早的实现来说根本不重要,因此他们甚至可能都不知道潜在的问题。无论如何,几乎每条指令都需要计算下一条指令,因此这似乎是合理的选择。

Of course, I can't say for sure.  What it looks like to me is that there was a choice to be made and it simply didn't matter for the earliest implementations, so they probably were not even aware of the potential issue.  Almost every instruction needs to compute instruction-next anyway, so this probably seemed like the logical choice.

充其量,他们可能节省了几条线,如pc-next确实是其他指令(例如调用)所必需的,而pc + 0则不是必须的。

At best, they might have saved a few wires, as pc-next is indeed required by other instructions (e.g. call) and pc+0 is not necessarily otherwise needed.

对以前的处理器的检查可能表明这只是完成操作的方式那时,所以这可能更多是继承现有方法,而不是设计选择。

An examination of prior processors might show this was just the way things were done back then, so this might have been more of a carry over of existing methods rather than a design choice.

8086没有流水线化(指令预取缓冲区除外),并且可变长度解码在开始执行之前已经找到一条指令的结尾。

8086 is not pipelined (other than the instruction prefetch buffer) and variable-length decoding has already found the end of an instruction before it starts to execute.

经过多年的事后分析,现在在RISC V中解决了这个数据路径问题。

With years of hindsight, this datapath issue is now addressed in RISC V.

我怀疑他们对此做出了相同水平的有意识的决定,例如对于分支延迟时隙(MIPS)。

I doubt they made the same level of conscious decision about this, as was done for example, for branch delay slots (MIPS).

根据评论中的讨论,8086可能没有d压入指令起始地址的所有异常。与更高版本的x86模型不同,除异常将div / idiv后的指令的地址压入。在8086中, cs rep movsb (或其他字符串指令)之后的中断恢复将推送最后一个前缀的地址,而不是整个指令(包括多个前缀)。 英特尔的8086手册(扫描的PDF)中记录了该错误。 。因此,很有可能8086确实没有记录指令的起始地址或长度,而只是记录了开始执行之前解码完成的地址。此至少由286固定,也许是186,但适用于所有8086/8088 CPU。

As per discussion in comments, 8086 may not have had any exceptions that push the instruction start address. Unlike on later x86 models, divide exceptions pushed the address of the instruction after div/idiv. And in 8086, interrupt-resume after cs rep movsb (or other string instruction) pushed the address of the last prefix, not the whole instruction including multiple prefixes. This "bug" is documented in Intel's 8086 manual (scanned PDF). So it's quite possible 8086 really didn't record the instruction start address or length, only the address where decoding finished before starting execution. This was fixed by at least 286, maybe 186, but applies to all 8086 / 8088 CPUs.

MIPS从一开始就具有虚拟内存,因此确实需要能够记录错误指令的地址,以便可以在异常返回后重新运行它。加上软件TLB未命中处理,还需要重新运行错误指令。但是异常的速度很慢,并且无论如何都会刷新管道,并且只有在获取之后才能检测到异常,因此无论如何都需要进行一些计算。

MIPS had virtual memory from the start, so it did need to be able to record the address of a faulting instruction so it could be rerun after exception-return. Plus software TLB-miss handling also required re-rerunning a faulting instruction. But exceptions are slow and flush the pipeline anyway, and aren't detected until well after fetch, so presumably some calculation would be needed regardless.

这篇关于从微体系结构抽象的x86程序计数器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆