“SIMT”架构的一些概念和设计对我来说仍然不清楚。
从我所看到和阅读的内容来看,分歧的代码路径和if()完全是一个相当糟糕的主意,因为许多线程可能会以锁步方式执行。那究竟是什么意思呢?怎么样:
kernel void foo(..., int flag)
{
if (flag)
DO_STUFF
else
DO_SOMETHING_ELSE
}
参数“flag”对于所有工作单位都是相同的,并且对所有工作单位采用相同的分支。现在,GPU是否会执行所有代码,尽管如此序列化所有内容并且基本上仍然采用未采用的分支?或者它是否更聪明,只会执行分支,只要所有线程都同意分支采取?这总是如此。
即。序列化是否总是发生或仅在需要时?抱歉这个愚蠢的问题。 ;)
答案 0 :(得分:3)
不,永远不会发生。仅当条件在本地工作组中的线程之间不一致时才执行两个分支,这意味着如果条件评估为本地工作组中的工作项之间的不同值,则当前生成的GPU将执行两个分支,但只执行正确的分支会写出价值并产生副作用。
因此,保持一致性对GPU分支的性能至关重要。
答案 1 :(得分:1)
不确定ati,但对于nvidia - 它很聪明。 如果warp中的每个线程都采用相同的方式,则不会有序列化。
答案 2 :(得分:1)
在您的示例中,flag对于所有工作项都具有相同的值,因此一个好的编译器将生成代码,这将使所有工作项处于相同的方向。
但请考虑以下情况:
kernel void foo(..., int *buffer)
{
if (buffer[get_global_id(0)])
DO_STUFF
else
DO_SOMETHING_ELSE
}
此处不保证所有工作项都采用相同的路径,因此需要消除序列化或控制流。