我有一个2位分支预测器,我的起始状态很弱,我需要计算预测精度:
for (int i=0; i < 100; i++)
{
for (int j=0; j < 50; j++)
{
...
}
}
因此,当i = 0时,我们取分支,因此我们在i = 0且j = 0并且将我们的预测器设置为强烈采用,对吧?所以,如果我们现在迭代j,这是否意味着我们没有采用新的分支?因为我们仍然在i = 0分支中,或者每次迭代都算作新分支?
答案 0 :(得分:0)
让我们首先手动将其编译成x86程序集以便更好地理解(任何其他人都可以):
mov ebx, 0 // this is our var i
.L0:
# /------------ inner loop start -----------\
mov eax, 0 // this is our var j
.L1:
// ...
add eax, 1
cmp eax, 50
jl .L1 // jump one
# \------------ inner loop end -------------/
add ebx, 1
cmp ebx, 100
jl .L0 // jump two
我认为即使您不熟悉汇编,此代码也非常直接:
0
0
// ...
1
添加到 eax 50
进行比较(这会在标志寄存器中设置一些位).L1:
1
添加到 ebx 50
进行比较(这会在标志寄存器中设置一些位).L0:
所以在第一次迭代中,我们到达跳一个并预测它将被采用。自eax < 50
起,我们将其更新为强烈接受。现在我们又做了48次。在50次迭代中,我们不会跳转,因为eax == 50
。这是单一错误预测,我们更新为弱拍。
现在我们第一次到达跳过两个。自ebx < 100
我们接受并将其更新为强烈接受。现在我们通过跳转到L0
来重新开始内循环。我们这样做了98次。在内循环的100次迭代中,我们不会跳转,因为ebx == 100
。这是单一错误预测,我们更新为弱拍。
所以我们用单一错误预测执行内部循环 100次,总共 100次错误预测 跳过一次和 100 * 49 = 4900
正确的预测。外部循环只执行一次,只有 1次误预测和 99
正确的预测。