众所周知,在GPU程序中进行分支非常昂贵,因为对于同一波中要评估的每个像素,它可能必须同时运行if和else逻辑,而只能将每个结果应用于适当的像素。

我很好奇,如果只有if语句而没有else语句,那么分支是否仍然是性能问题?

在这种情况下,与无分支逻辑相比,它似乎有更快的能力,如果没有像素需要在if语句内执行工作,而是可以跳过它作为一个组,则为这种情况。

这是真的吗?还有其他缺点吗?像是较旧的视频卡仍然可以执行if逻辑,即使没有像素评估为真?

#1 楼

如果没有差异(即wave中的所有线程都在同一分支中),则较新的GPU可以跳过if分支内的所有工作。如果存在差异,则两个分支中的代码都将执行,但是线程执行掩码基本上定义了哪个线程在哪个分支中执行代码(未执行的线程中的分支中的代码实际上被NOP了)。这基本上与谓词分支相同,但会根据差异动态发生。

在GCN架构上,至少分支本身基本上是免费的或至少非常便宜(由与ALU并行运行的独立单元处理)例如),但要记住的是,分支也会增加GPR压力,从而降低占用率。低占用率意味着一次飞行中的线程数会减少,这会影响GPU隐藏内存延迟的能力。根据着色器访问内存的方式,这可能不是您着色器中的问题,即您应该看到性能提高以及具有大量内存访问权限的着色器的占用率增加。

因此优化仍然是一件好事在合理的情况下进行分支,但我认为这是需要留给着色器发挥最大性能的优化阶段的事情之一。

#2 楼

旧硬件
一些较旧的卡过去不曾在经线中跳转指令,因此这确实是一个问题。如果您有使用这些卡的条件,则即使未通过任何像素,顶点等输入该块,该条件的内部逻辑仍将被评估。在这种情况下您无能为力,因为每条指令都会被执行。最坏的情况也是最好的情况。
现代硬件
但是,如果您使用的是相对较新的硬件,这不是问题,并且在必要时将跳过“ if / else”块。与不使用“ if / else”块相比,使用“ if / else”块确实不应该有任何弊端。您仍在使用“其他”少的语句进行分支。实际上,某些后处理效果/延迟渲染特别受益于此。
最坏的情况是某些线程通过“ if”块,其余线程通过“ else”块。最好的情况是所有内容都通过“ if”块或“ else”块。根据需要使用“ if / else”条件(在旧硬件或更新的硬件上)没有不利之处,但是更新的硬件可能会有不利之处。

评论


$ \ begingroup $
如果不是所有浪潮都想走同一条道路,是否还有不利之处?难道不是两条路都行吗?我还想知道您在上一段中关于较新的卡具有双倍逻辑的含义?感谢您的回答和信息(:
$ \ endgroup $
–艾伦·沃尔夫(Alan Wolfe)
16-10-11在14:34

$ \ begingroup $
忽略最后一段,我将编辑答案。我以为您正在尝试做其他事情,但我做了一个错误的假设。如果整个经线没有通过相同的路径,那么您是对的,那么即使对于较新的卡,也必须经过“ if”和“ else”块。
$ \ endgroup $
–aces
16-10-12在4:09