这不是解码的问题,通常是在 8086 上获取。
启动两个单独的指令解码操作可能比仅为一个获取更多微代码更昂贵loop
操作说明。我猜这就是下表中不包括代码获取瓶颈的数字的原因。
同样或更重要的是,8086 经常受到内存访问(包括代码获取)的瓶颈。 (8088 几乎总是如此,它的 8 位总线像吸管一样呼吸,这与 8086 的 16 位总线不同)。
dec cx
是1个字节,jnz rel8
是2个字节。
总共 3 个字节,而 2 个字节loop rel8
.
8086性能可以通过计算内存访问次数并乘以四来近似 https://retrocomputing.stackexchange.com/questions/3255/when-specifying-intel-80x86-instruction-execution-time-what-is-included-in-the/3292#3292,因为其 6 字节指令预取缓冲区允许其将代码获取与其他指令的解码和执行重叠。 (除了非常慢的指令,例如mul
这将使缓冲区在最多 3 次 2 字节读取后填满。)
也可以看看提高 8086 二进制 -> 格雷码的效率 https://stackoverflow.com/questions/67400133/increasing-efficiency-of-binary-gray-code-for-8086有关针对 8086 进行优化的示例,以及指向更多资源(例如指令时序表)的链接。
https://www2.math.uni-wuppertal.de/~fpf/Uebungen/GdR-SS02/opcode_i.html https://www2.math.uni-wuppertal.de/%7Efpf/Uebungen/GdR-SS02/opcode_i.html有 8086 的指令时序(我认为取自英特尔手册,如 njuffa 的答案中引用的那样),但这些是only当获取不是瓶颈时执行。 (即仅从预取缓冲区进行解码。)
解码/执行时序,不包括获取:
DEC Decrement
operand bytes 8088 186 286 386 486 Pentium
r8 2 3 3 2 2 1 1 UV
r16 1 3 3 2 2 1 1 UV
r32 1 3 3 2 2 1 1 UV
mem 2+d(0,2) 23+EA 15 7 6 3 3 UV
Jcc Jump on condition code
operand bytes 8088 186 286 386 486 Pentium
near8 2 4/16 4/13 3/7+m 3/7+m 1/3 1 PV
near16 3 - - - 3/7+m 1/3 1 PV
LOOP Loop control with CX counter
operand bytes 8088 186 286 386 486 Pentium
short 2 5/17 5/15 4/8+m 11+m 6/7 5/6 NP
因此,即使忽略代码获取差异:
-
dec
+ 采取jnz
在 8086 / 8088 上解码/执行需要 3 + 16 = 19 个周期。
- taken
loop
在 8086 / 8088 上解码/执行需要 17 个周期。
(采取的分支在 8086 上很慢,并且丢弃预取缓冲区;没有分支预测。我不知道这些计时是否包括任何这种惩罚,因为它们显然不适用于其他指令和非采取的分支。)
除代码预取缓冲区外,8088/8086 不采用流水线方式。完成一条指令的执行并开始下一条指令的解码/执行需要一些时间;即使是最便宜的说明(例如mov reg,reg
/ 移动 / 旋转 /stc
/std
/等)需要2个周期。奇怪的是超过nop
(3 个周期)。