6

我正在研究有关动态语言 VM 实现的 JIT 设计。自从 8086/8088 天以来,我没有做太多的组装,只是在这里或那里做了一点,所以如果我心情不好,那就太好了。

据我了解,x86 (IA-32) 架构今天仍然具有与以往相同的基本受限寄存器集,但内部寄存器数量已大幅增长,但这些内部寄存器通常不可用,并与寄存器重命名一起使用实现代码的并行流水线,否则无法并行化。我非常理解这种优化,但我的感觉是,虽然这些优化有助于提高整体吞吐量和并行算法,但我们仍然坚持使用的有限寄存器集会导致更多的寄存器溢出开销,如果 x86 有两倍或四倍的寄存器对我们可用,典型指令流中的推送/弹出操作码可能会显着减少?或者是否有其他处理器优化也可以优化这一点,我不知道?基本上如果我

任何关于研究的参考,或者更好的是,个人经历?

编辑:x86_64 有 16 个寄存器,是 x86-32 的两倍,感谢您的更正和信息。

4

2 回答 2

10

除了重命名寄存器以隐藏由于指令延迟导致的气泡之外,大多数 x86 架构都足够智能,可以计算推送和弹出,并将它们重命名到寄存器中。请记住,x86 上的指令解码器实际上执行了一种 JIT 编译,将 x86 指令流转换为存储在跟踪缓存中的小型微码程序。此过程的一部分包括拦截小偏移堆栈负载并将其转换为寄存器。因此类似于(显然愚蠢和纯粹的例子):

lwz eax,[ebp]
lwz ebx,[ebp+4]
add eax,[edx+0]
push eax 
lwz eax,[ebp+8]
add eax,ebx
pop ebx
add eax,ebx

煮成类似的东西(假装内部寄存器被命名为例如r0..r16):

lw r3, edx
lw r1, ebp
lw r2, ebp+4 ; the constant '4' is usually stored as an immediate operand
add r1,r2
or r4,r1,r1 ;; move r1 to r4
lw r1, ebp+8
add r1,r2
or r2,r4,r4
add r1,r2

当然,一个神奇的智能解码器(与实际适合晶体管数量的解码器不同)会破坏那里的一些不必要的移动,但我要说明的是,推送/弹出和存储/加载esp+(some small number)实际上变成了影子寄存器。

于 2010-03-17T07:10:58.563 回答
4

两点:

(1) x86-64 寄存器数量翻倍到16个

(2) 在现代 x86 CPU 中,使用已在 L1 缓存中的内存位置的指令几乎与使用寄存器操作数的相同操作一样快,因此您几乎可以将 L1 视为“寄存器内存”

于 2010-03-17T10:23:05.437 回答