如何在CUDA中用较少的线程调用_设备_函数

如何在CUDA中用较少的线程调用_设备_函数,cuda,Cuda,我想从执行基数排序的内核内部调用一个独占扫描函数。但是独占扫描只需要一半的线程就可以完成它的工作 独占扫描算法需要几个_syncthreads()。如果一开始我有一个陈述,比如 如果(threadIdx.x>NTHREADS/2)返回 这些线程将不参与独占扫描同步线程,这是不允许的。 有没有办法解决这个问题。我确实有对独占扫描的调用,它被_syncthread()s包围。类似的东西应该可以工作(不要使用提前返回): \uuuu syncthreads();//在进入独占扫描区域时 //开始独占扫

我想从执行基数排序的内核内部调用一个独占扫描函数。但是独占扫描只需要一半的线程就可以完成它的工作

独占扫描算法需要几个_syncthreads()。如果一开始我有一个陈述,比如

如果(threadIdx.x>NTHREADS/2)返回

这些线程将不参与独占扫描同步线程,这是不允许的。
有没有办法解决这个问题。我确实有对独占扫描的调用,它被_syncthread()s包围。

类似的东西应该可以工作(不要使用提前返回):

\uuuu syncthreads();//在进入独占扫描区域时
//开始独占扫描功能
如果(threadIdx.x

这有点乏味,但这是我所知道的唯一遵守
\uu syncthreads()
法律条文的方法。您还可以尝试按照您指定的方式保留代码,让不做任何工作的线程提前返回/退出。它可能会起作用,可能会起作用。但不能保证它能在未来的体系结构或更新的工具链中工作。

只需指出另一种选择:
您还可以使用相当于
\uuuu syncthreads()
的内联程序集,该程序集允许使用可选参数表示compute capability 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);
免责声明:写在浏览器中,完全未经测试


不过,这是否值得麻烦是另一个问题。

我学习了一些关于内联asm so+1的知识,但是
\uuuSyncThreads
已经并且总是按照扭曲中的线程数递增——不多也不少——即使发散分支中只有一个线程命中
\uSyncThreads
。这实际上使它成为一种指令。
#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);