CUDA __syncthreads()和递归

时间:2011-07-19 10:01:07

标签: recursion cuda

我想将__syncthreads()用于递归,如

__device__ void foo(int k) {
  if (some_condition) {
    for (int i=0;i<8;i++) { 
       foo(i+k); // foo might take longer with some inputs
       __syncthreads();
    }
  }
}

这__syncthreads()现在如何应用?我知道它只适用于一个区块。据我所知,这适用于所有本地线程,与递归深度无关?但是如果我想确保这个__syncthreads()到某个递归深度呢?这甚至可能吗?我可以检查递归深度,但我相信这也行不通。

有可能的替代方案吗?

我已经看到CUDA设备有3个syncthread扩展&gt; = 2.0

int __syncthreads_count(int predicate);
int __syncthreads_and(int predicate);
int __syncthreads_or(int predicate);

但我不认为他们会有所帮助,因为它们看起来像是一个原子计数器。

3 个答案:

答案 0 :(得分:7)

如您所知,__syncthreads()仅在块内的所有线程都到达屏障时才是安全的。这意味着如果从条件中调用__syncthreads(),条件必须在块中的所有线程上评估为相同。

对于递归中的__syncthreads(),这意味着块中的所有线程必须执行到相同深度的递归,否则并非所有线程都将达到相同的屏障。

答案 1 :(得分:2)

  

有可能的替代方案吗?

是的,不要使用递归范例来表达你的函数逻辑

答案 2 :(得分:0)

当然你对__syncthreads()所说的是真的,它只适用于块中的本地线程,因此你无法控制其他块中发生的事情。减少的最佳方法是首先对整个数组进行减少,这通常是一个等于块大小的数组。然后不要将数组复制回主机,而是调用另一个减少,这将有1个块和线程类似于前一个调用中的块数,然后将大小为1的数组从Device复制到Host。但请确保在两次调用之间使用cudaThreadSynchronize(),除非生成第一次减少,否则可以进行减少。这是两步减少,但它适用于我。

欢呼!!! SAIF