分支预测器如何知道它是否不正确?

时间:2014-07-20 16:41:10

标签: caching assembly architecture cpu

这是我第二次提出这个问题;有人第一次回复,但我花了太长时间回复他们,因此没有得到充分的理解。

我想要做的是了解更多关于现代架构的取指令部分;我假设所有指令都由分支预测器预测,指令获取单元按预测获取。

另一位试图帮助提及有关分支指令的绅士"也与预测的指令一起发送。这个"分支指令"测试分支预测器的预测条件是否正确。我还假设这些分支指令转到分支执行单元,DONT需要来自内存的任何加载。

我不明白的是:

  • 分支执行单元如何通过该指令知道猜测是否正确?
  • 一旦知道它是正确的,会发生什么?
  • 每次预测都会发出分支指令(基本上意味着......每次预测都会发生吗?)
  • 分支预测必须在预测指令之前或之后进行吗?
  • 分支指令是否需要从内存中加载任何数据?如果是这样,它是什么?

谢谢!

1 个答案:

答案 0 :(得分:5)

我想回答您的问题,首先需要了解分支预测的工作原理。要解释它必须知道为什么它首先做出这些预测。这需要了解现代处理器中的管道如何工作。我要解释的最好方法是从非流水线CPU处理指令开始。

(如果我查看你已经知道的事情,请耐心等待。不清楚你对分支预测的困惑源于何处。)

较旧的CPU以及许多简单的现代CPU以相当简单明了的方式处理指令。他们将执行指令所需的操作分解为一系列步骤。每条指令都通过这些步骤运行,一旦完成所有指令,它就会继续执行下一步。例如,假设的简单非流水线CPU可能会遵循以下一系列步骤:

  1. 将指令读入内存。
  2. 读入指令的操作数。
  3. 执行该指令的操作。
  4. 写下结果
  5. 以这种方式实现CPU相对简单,但它使得处理器资源的使用非常低效。当CPU在执行和指令过程中执行一个步骤时,用于实现其他步骤的所有硅片都是空闲的。

    现代流水线处理器通过将执行指令所需的步骤顺序转换为装配线等方式来提高效率。指令是一系列步骤,或者它们被调用的阶段,就像在非流水线CPU中一样。不同之处在于,一旦指令清除了流水线的第一级,CPU就可以向下发送另一条指令。这允许多个指令同时进入流水线,希望能够很好地利用芯片的所有部分。虽然指令仍然需要经历许多不同的阶段,但理想情况下,指令会一个接一个地快速地从管道中出来。流水线操作不会缩短从开始到结束执行指令的时间,而是缩短指令执行之间的时间。

    现在这是对现代管道的一个相当简单的描述,这个管道掩盖了许多问题,使现代流水线CPU的设计变得复杂。然而,就分支预测而言,只有一个复杂因素需要解决:执行分支指令时会发生什么。

    首先,没有什么特别需要关闭分支指令本身。它可以像其他任何一样被抛到管道上。一旦它清除了第一阶段,CPU就可以发送下一条指令,其中存在问题。下一条指令是什么?由于它是一个分支,它可以采用两种不同的方式,在分支指令完成通过管道之前,CPU不知道哪一个。

    处理器要做的事情就是等待。由于在等待时没有其他指令被送入管道,因此管道会清空。只有当分支指令退出现在为空的管道时,CPU才能恢复输入指令。下一条指令必须通过现在为空的管道的所有阶段,导致分支指令完成和下一条指令之间的延迟确实。在这种情况下,指令不会像理想的那样快速连续退出管道。

    这种延迟在现代处理器上可能相当大,它在管道中的数量级的功能,基本上每个阶段一个周期。大多数现代x86 CPU在其管道中大约有15个阶段,因此以这种方式实现分支将是非常昂贵的。具有非常短的流水线的简单CPU可能能够随时待命,但现代处理器必须做其他事情。他们做出预测。

    最简单的预测形式是静态分支预测。处理器只查看分支指令本身来猜测它是否会被采用。最简单的静态预测形式是假设不采用所有分支,因为这种情况经常发生。更先进的静态预测器假定分支向后移动而前进分支不是。这假设后向分支是循环,循环通常不止一次执行。

    静态预测可以很好地运行,但它仍然会做出很多糟糕的预测。您可以通过采用某种动态分支预测来改进这一点。对于许多人来说,可以采取各种不同的方式,但是他们都根据以前分支的历史记录进行了猜测。

    然而,CPU最终进行预测,就像它做出了正确的猜测一样。在将分支指令放入管道之后,它开始发送它假定将执行的指令。这称为推测执行,并且像这样处理的指令被标记为推测性的。这让管道知道它不应该对这些无法撤消的指令做任何事情。

    当分支指令到达管道的末尾时,CPU现在将知道它的猜测是否正确。如果它做出正确的预测,它不需要做任何事情,它可以让前面的指令完成通过管道的旅程。因为它猜对了,分支没有额外的费用。

    如果它猜错了它必须撤消推测执行的指令可能已经完成的任何事情,清除管道并开始发送它应该执行的指令。这导致了相同的延迟,就好像它根本没有做出预测一样。

    所以问题的答案"分支预测器如何知道它是否不正确?"如果它做出正确的预测,它是不知道也不关心的。它只是做出预测。如果它是一个动态分支预测器,那么它将记录分支是否在其历史记录中被采用,但它不会记录它是否做出了正确的决定。