【发布时间】:2010-11-09 02:40:55
【问题描述】:
以下是两个 Pentium 组装序列列表中的剪辑。我们有一个外部循环,它试图为我们的序列计时,并正在做一个调用表来访问这些例程。因此,每次都是从同一位置拨打外线电话。这两个序列的不同之处在于第一个序列比第二个序列少一条指令。
我们在两台 Intel 机器上得到的结果非常不同。
CPUID 指令告诉 Family、Model 和 Stepping。
机器 1:Family 6,Model 15 步进 11. CPUZ 报告“Intel Core 2 Duo E6750”
指令以统计上相同的速度执行。
机器 2:Family 15,Model 3,Stepping 3。CPUZ 报告“Intel Pentium 4”
第一个序列比第二个序列花费大约 8% 的时间。
我们根本无法解释时间的增加。不应该有任何不同的标志延迟、分支预测、寄存器使用问题等。至少我们无法判断。
有谁知道为什么在一台机器上执行第一个序列需要更长的时间?
编辑:在第一个序列中添加“XOR PTR ereg, 0”确实使时间与 Pentium 4 上的第二个匹配。好奇。
第一个序列:
00000040 ALUSHIFT_AND_C_V_E LABEL NEAR
00000040 0F B7 04 55 MOVZX EAX, gwr[(SIZEOF WORD) * EDX] ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
00000000 E
00000048 0F B7 14 4D MOVZX EDX, gwr[(SIZEOF WORD) * ECX] ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
00000000 E
00000050 23 C2 AND EAX, EDX ; AX = L&R (result)
00000052 A3 00000000 E MOV dvalue, EAX ; Save the temporary ALU/Shifter result
00000057 C3 RET ; Return
第二个序列:
00000060 ALUSHIFT_AND_C_V_NE LABEL NEAR
00000060 0F B7 04 55 MOVZX EAX, gwr[(SIZEOF WORD) * EDX] ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
00000000 E
00000068 0F B7 14 4D MOVZX EDX, gwr[(SIZEOF WORD) * ECX] ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
00000000 E
00000070 23 C2 AND EAX, EDX ; AX = L&R (result)
00000072 80 35 00000000 E XOR BYTE PTR ereg, 1 ; E = ~E
01
00000079 A3 00000000 E MOV dvalue, EAX ; Save the temporary ALU/Shifter result
0000007E C3 RET ; Return
【问题讨论】:
-
看起来类似于我问的一个问题:stackoverflow.com/questions/688325/…
-
是 ALUSHIFT_AND_C_V_E LABEL NEAR 和 ALUSHIFT_AND_C_V_NE LABEL NEAR 两个序列吗?如果是这样,您可能应该将它们放在单独的块中以使代码更易于阅读。
-
知道我们在谈论哪个 CPU 也很好(用人名,而不是 CPUID 字符串)
-
@Mark:谢谢。我已经根据您收到的一些答案开始调查。 @jalf:我编辑了你的优秀建议。