gpgpu:为什么我们不需要在细粒度多线程中进行分支预测?

时间:2014-08-24 17:40:30

标签: cuda opencl gpgpu branch-prediction

当波前执行时,它提供细粒度多线程。其中一个后果是没有分支预测要求,如下面的幻灯片所示:

enter image description here

但我无法理解这一点。有人可以用一种简单的方式解释这个吗?

3 个答案:

答案 0 :(得分:5)

分支在执行指令流时引入了显着的延迟。如果处理器不支持推测性执行,则在执行分支条件之前不允许执行任何指令。如果采用分支,则处理器需要获取新的指令行,从而引入额外的延迟。如果未采用分支,则可以继续执行。在深度管道上,条件的评估可以引入10-20个循环。分支预测和推测执行允许处理器继续执行附加指令或者如果采用分支则开始提前获取指令。如果分支预测不正确,则必须抛出(回滚)分支后面的所有指令。

分支预测硬件在面积方面通常很昂贵,但即使是基本的分支预测(可能采用也可能不采取)可以显着改善IPC。

GPU至少有三个原因不倾向于实现分支预测:

  1. 分支预测的目标是通过推测执行指令来改进IPC,而不是等待条件结果和可能的附加指令获取。 GPU旨在通过在多个执行线程之间切换来隐藏延迟。当warp / wavefront等待确定分支条件的结果时,可以发出其他warp / wavefronts以隐藏延迟。

  2. 分区历史表在面积方面很昂贵。

  3. 就面积而言,投机执行费用很高。

答案 1 :(得分:3)

它在幻灯片中说每次只有一条指令在管道中。分支预测的目的是防止指令管道填满错误的分支(仅加载if部分以实现它应该将else指令加载到管道中)。如果只有一条指令在管道中,因为在您意识到它是错误的分支之前,您没有投资填充x阶段的管道(快速谷歌:最多30个cpus),这是不需要的,必须冲洗管道并重新开始。

答案 2 :(得分:1)

一些细节取决于实际的GPU架构。但是一个简单的例子,除了Trudbert已经给出的答案(+1):

对于像这样的分支

if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
}

可能有一组语句为true的线程,以及另一组语句为false的线程。可以想象它就好像语句为false的线程只是等待,直到其他人完成了他们的工作。

类似地,对于像这样的分支

if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
} else {
    data[threadIndex] = 0.0;
}

可以想象这是所有线程执行分支的两个路径,并确保来自"错误"的结果。路径被忽略。这被称为"谓词执行"。

(有关此内容的更多详细信息,请参阅GPU Gems 2, Chapter 34

所以,因为预测"对"没有优势。分支(因为每个线程无论如何都必须占用所有分支),没有理由引入分支预测。