如何用更少的线程调用CUDA中的__device__函数

时间:2013-03-18 18:12:05

标签: cuda

我想从进行基数排序的内核中调用独占扫描函数。但独占扫描只需要一半的线程来完成它的工作。

独占扫描算法需要多个__syncthreads()。如果我在开始时有一个声明,如

  

if(threadIdx.x> NTHREADS / 2)返回;

这些线程不会参与独占扫描同步传输,这是不允许的。 有没有办法解决这个问题。我确实调用了由__syncthread()s包围的独占扫描。

2 个答案:

答案 0 :(得分:4)

这样的事情应该有用(不要使用早期的回报):

__syncthreads(); // at entry to exclusive scan region
// begin exclusive scan function
if (threadIdx.x < NTHREADS/2) {
  // do first phase of exclusive scan up to first syncthreads
  }
__syncthreads(); // first syncthreads in exclusive scan function
if (threadIdx.x < NTHREADS/2) {
  // do second phase of exclusive scan up to second syncthreads
  }
__syncthreads(); // second syncthreads in exclusive scan function
(... etc.)
__syncthreads(); // at exit from exclusive scan region

这有点单调乏味,但这是我所知道的唯一方法是坚持__syncthreads() usage的法律条文。您也可以尝试按照您指示的方式保留代码,使用不执行任务的线程会提前返回/退出。它可能只是工作,可能会工作。但是不能保证它将适用于未来的架构或更新的工具链。

答案 1 :(得分:2)

只是指出一个替代方案:
您还可以使用等效于__syncthreads()的内联程序集,它允许使用可选参数作为计算功能2.0以后可用的参与线程数。这样的事情应该有效:

#define __syncthreads_active(active_threads) asm volatile("bar.sync 0, %0;" :: "r"(active_threads));

if(threadIdx.x >= NTHREADS/2) return;

int active_warps = (NTHREADS/2 + warpSize) / warpSize;
int active_threads = active_warps * warpSize; // hopefully the compiler will optimize this to a simple active_threads = (NTHREADS/2 + warpSize) & ~32

__syncthreads_active(active_threads);
// do some work...
__syncthreads_active(active_threads);
// do some more work...
__syncthreads_active(active_threads);

免责声明:写在浏览器中并且完全未经测试!

值得麻烦的是另一个问题。