CUDA如何在障碍和条件表达式中完全同步warp中的线程?

时间:2012-07-27 12:10:10

标签: cuda synchronization conditional

我最近问了一个关于CUDA中块的线程之间的同步问题的问题,这里:Does early exiting a thread disrupt synchronization among CUDA threads in a block?我的问题的一条评论给出了一个类似线程的链接,引用了以下关于CUDA屏障的内容(__syncthreads())来自PTX指南的说明:

  

在每个warp的基础上执行障碍,就好像warp中的所有线程都是活动的一样。因此,如果warp中的任何线程执行bar指令,则好像warp中的所有线程都执行了bar指令。 warp中的所有线程都会停止,直到屏障完成,并且屏障的到达计数会增加warp大小(而不是warp中活动线程的数量)。在有条件执行的代码中,只有在已知所有线程以相同方式评估条件(warp不发散)时才应使用bar指令。由于障碍是在每个warp的基础上执行的,因此可选的线程数必须是warp大小的倍数。

我仍然对本引文中解释的机制感到有些困惑。它说如果我们在条件代码中使用障碍,并且如果某些线程通过在条件代码上采用不同的路径而无法到达屏障指令,那么它可能导致未定义的行为甚至死锁。问题是,我不明白这种机制如何导致死锁。 (即使是不是warp大小的倍数的线程数也是危险的。)文档说如果即使单个线程执行bar指令,它也会被视为warp中的所有线程执行warp指令和到达计数器由warp中的线程数更新。可能CUDA架构通过检查此到达计数器来确定是否所有线程已经同步;通过将它与块中的实际线程数进行比较。如果它是基于每个线程更新的,那么这可能会导致死锁,因为计数器永远不会达到最大值。 NUM。由于其中一些线程采用不包含bar指令的条件路径。但是在这里,数字会根据warp中的线程数进行更新。所以,我并不完全理解这里的潜在机制。

我的另一个问题是关于整体的条件陈述。我知道warp中的所有线程在给定时间执行相同的指令,并且在if子句的情况下,采用if和else分支的线程通过保持空闲并在条件结束时再次同步来等待彼此。因此,对于这种条件代码存在隐式同步机制。现在,它将如何在如下代码中工作:

int foundCount=0;
for(int i=0;i<array1_length;i++)
{
    for(j=0;j<array0_length;j++)
    {
        if(i == array0[j])
        {
            array1[i] = array1[i] + 1;
            foundCount++;
            break;
        }
    }

     if(foundCount == foundLimit)
        break;
}

这是我当前任务的一段代码;对于array1的每个成员,我需要检查array0是否包含当前的array1索引。如果是这样的话,我在array1中增加当前索引的元素,因为它已经被array0包含,所以我用break语句退出内部循环。如果array1的索引总数达到限制,我们不需要继续外循环,我们也可以退出它。这对于CPU代码来说很简单,但我想知道CUDA的warp机制如何处理这种嵌套的条件情况。想象一下,32个线程的warp正在处理这个代码,其中一些可以处理内部循环,而其中一些已经退出它,其中一些甚至可以退出外部循环。在这种情况下,体系结构如何组织线程的工作,它是否包含线程的当前“等待点”列表?它是如何确保在这种复杂情况下同一warp中的线程处理同一行代码的?

0 个答案:

没有答案