Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cuda gpgpu:为什么在细粒度多线程中不需要分支预测?_Cuda_Opencl_Gpgpu_Branch Prediction - Fatal编程技术网

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

Cuda gpgpu:为什么在细粒度多线程中不需要分支预测?,cuda,opencl,gpgpu,branch-prediction,Cuda,Opencl,Gpgpu,Branch Prediction,当波阵面执行时,它提供细粒度的多线程处理。这样做的后果之一是没有如下幻灯片所示的分支预测要求: 但我无法理解这一点。有人能简单地解释一下吗 幻灯片中说,每次管道中只有一条指令。分支预测的目的是防止指令管道充满错误的分支(加载if部分只是为了实现它应该将else指令加载到管道中)。如果只有一条指令在管道中,这是不需要的,因为在你意识到它是错误的分支之前,你没有足够的投资来填充管道的x个阶段(快速谷歌:CPU最多30个),必须刷新管道并重新开始。幻灯片中说,每次管道中只有一条指令。分支预测的目的是

当波阵面执行时,它提供细粒度的多线程处理。这样做的后果之一是没有如下幻灯片所示的分支预测要求:


但我无法理解这一点。有人能简单地解释一下吗

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

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

一些细节取决于实际的GPU体系结构。但是,除了Trudbert已经给出的答案(+1)之外,还有一个简化的示例:

像这样的树枝

if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
}
if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
} else {
    data[threadIndex] = 0.0;
}
可能有一组线程的语句为
true
,另一组线程的语句为
false
。可以想象,语句为
false
的线程只是等待其他线程完成其工作

类似地,对于这样的分支

if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
}
if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
} else {
    data[threadIndex] = 0.0;
}
可以想象,所有线程都执行分支的两条路径,并确保忽略“错误”路径的结果。这被称为“谓词执行”

(有关详细信息,请参阅)


因此,由于预测“正确”分支没有任何优势(因为每个线程无论如何都必须接受所有分支),因此没有理由引入分支预测。

一些细节取决于实际的GPU体系结构。但是,除了Trudbert已经给出的答案(+1)之外,还有一个简化的示例:

像这样的树枝

if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
}
if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
} else {
    data[threadIndex] = 0.0;
}
可能有一组线程的语句为
true
,另一组线程的语句为
false
。可以想象,语句为
false
的线程只是等待其他线程完成其工作

类似地,对于这样的分支

if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
}
if (data[threadIndex] > 0.5) {
    data[threadIndex] = 1.0;
} else {
    data[threadIndex] = 0.0;
}
可以想象,所有线程都执行分支的两条路径,并确保忽略“错误”路径的结果。这被称为“谓词执行”

(有关详细信息,请参阅)


因此,由于预测“正确”分支没有任何优势(因为每个线程无论如何都必须接受所有分支),因此没有理由引入分支预测。

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

分支预测硬件通常在面积方面比较昂贵,但即使是基本分支预测(可能采用与可能不采用)也可以显著提高IPC

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

  • 分支预测的目标是通过推测执行指令而不是等待条件结果和可能的额外指令获取来改进IPC。GPU被设计为通过在多个执行线程之间免费切换来隐藏延迟。当扭曲/波前等待确定分支条件的结果时,可以发出其他扭曲/波前以隐藏延迟

  • 分支历史记录表在面积方面很昂贵

  • 投机执行在面积上是昂贵的


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

    分支预测硬件通常在面积方面比较昂贵,但即使是基本分支预测(可能采用与可能不采用)也可以显著提高IPC

    GPU不倾向于为at实现分支预测