CUDA:Divergent扭曲惩罚细节

时间:2013-07-02 07:52:01

标签: cuda

我试图理解下一段代码中warp散度的惩罚是什么。我理解原则上如何处理warp散度(小分支的预测指令,warp投票和大分支的分支 - 如果所有warp同意,否则预测指令和没有分支,与小分支相同)。但是,我不明白具体细节 - 如何处理带有break / continue的while循环。

在下面的示例中,当scrapEverythingCondition()对于通道X评估为true时,将发生以下哪种情况:

  1. 评估在内循环中进行,直到n == N_N,泳道X在整个时间内评估nops,i递增,所有泳道现在一起工作。
  2. 除了车道X之外的所有人都执行someMoreWork()而车道X评估nops,车道X执行someCostlyInitialization()后跟n = 0,而其他人评估nops,所有车道继续一起评估内部循环(显然具有不同的n值)
  3. 我没想到的其他东西。
  4. 代码:

    __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循环耗尽)。

2 个答案:

答案 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