我试图理解下一段代码中warp散度的惩罚是什么。我理解原则上如何处理warp散度(小分支的预测指令,warp投票和大分支的分支 - 如果所有warp同意,否则预测指令和没有分支,与小分支相同)。但是,我不明白具体细节 - 如何处理带有break / continue的while循环。
在下面的示例中,当scrapEverythingCondition()对于通道X评估为true时,将发生以下哪种情况:
代码:
__global__ void chainKernel() {
int i = threadIdx.x + blockIdx.x * blockDim.x;
while (i < N_I) {
someCostlyInitialization();
for(int n = 0; n < N_N; ++n) {
someStatisticsComputations(n);
if (scrapEverythingCondition(n)) {
// Everything we did for current i is no good. Scrap and begin again
i -= BLOCKS*THREADS;
break;
}
someMoreWork();
}
i += BLOCKS*THREADS;
}
}
我尝试编译到PTX并查看生成的代码但对我来说太复杂了:(
编辑:感谢Maku的回答。我还能够使用传统代码中的老式printf()来验证答案。我能够看到哪些线程在哪里以及以什么顺序获得,并且实际上选项1是正确的(通道X被暂停,直到内部for循环耗尽)。答案 0 :(得分:0)
我在这个问题上找到了一个有趣的文档:pdf
据我所知,控制流语句(包括break
)定义了线程的同步点。在你的情况下,它将在
i += BLOCKS*THREADS;
因此,通道X离开for
循环并等待其他线程到达上述行。
答案 1 :(得分:0)
在我的理解中,scrapEverythingCondition(n)为true的所有线程都执行if块内的内容并退出for循环。在执行此块之前,将阻止所有其他线程。当这些线程退出for循环时,其他trhead将执行someMoreWork();
试用NVidia Visual Profiler。它真的有助于分析这些问题。
以下是关于此的一些信息(第13 - 18页):
http://mc.stanford.edu/cgi-bin/images/3/34/Darve_cme343_cuda_3.pdf