2位分支预测器,带有两个for循环

时间:2017-02-20 01:10:23

标签: cpu-architecture

我有一个2位分支预测器,我的起始状态很弱,我需要计算预测精度:

for (int i=0; i < 100; i++)
{
   for (int j=0; j < 50; j++)
   {
   ...
   }
}

因此,当i = 0时,我们取分支,因此我们在i = 0且j = 0并且将我们的预测器设置为强烈采用,对吧?所以,如果我们现在迭代j,这是否意味着我们没有采用新的分支?因为我们仍然在i = 0分支中,或者每次迭代都算作新分支?

1 个答案:

答案 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

我认为即使您不熟悉汇编,此代码也非常直接:

  • ebx 设置为0
  • 跳两个回到这里
    • eax 设置为0
    • 跳一个人回到这里
      • 执行我们的循环代码// ...
      • 1添加到 eax
      • eax 50进行比较(这会在标志寄存器中设置一些位)
      • 如果eax不是50,则跳转到标签.L1:
    • 1添加到 ebx
    • ebx 50进行比较(这会在标志寄存器中设置一些位)
    • 如果ebx不是100,则跳转到标签.L0:
  • 循环结束

所以在第一次迭代中,我们到达跳一个并预测它将被采用。自eax < 50起,我们将其更新为强烈接受。现在我们又做了48次。在50次迭代中,我们不会跳转,因为eax == 50。这是单一错误预测,我们更新为弱拍。

现在我们第一次到达跳过两个。自ebx < 100我们接受并将其更新为强烈接受。现在我们通过跳转到L0来重新开始内循环。我们这样做了98次。在内循环的100次迭代中,我们不会跳转,因为ebx == 100。这是单一错误预测,我们更新为弱拍。

所以我们用单一错误预测执行内部循环 100次,总共 100次错误预测 跳过一次 100 * 49 = 4900正确的预测。外部循环只执行一次,只有 1次误预测 99正确的预测