如果不能在条件分支中调用 CUDA,如何在 CUDA 中减少__syncthreads?
How to reduce in CUDA if __syncthreads can't be called inside conditional branches?
NVIDIA建议的约简方法在条件分支内使用__syncthreads()
,例如:
if (blockSize >= 512) { if (tid < 256) { sdata[tid] += sdata[tid + 256]; } __syncthreads(); }
或
for (unsigned int s=blockDim.x/2; s>32; s>>=1)
{
if (tid < s)
sdata[tid] += sdata[tid + s];
__syncthreads();
}
在第二个例子中,__syncthreads()
在for
循环体内,这也是一个条件分支。
然而,关于SO的一些问题在条件分支内提出了__syncthreads()
的问题(例如,我可以在丢弃线程后使用__syncthreads()吗?条件同步线程&死锁(或不死锁),答案说条件分支中的__syncthreads()
可能导致死锁。因此,NVIDIA建议的约简方法可能会死锁(如果相信答案所基于的文档)。
此外,如果_syncthreads()
不能在条件分支中使用,那么恐怕很多基本的操作都会被阻塞,约简只是一个例子。
那么如何在没有使用__syncthreads()
条件分支的情况下减少CUDA ?或者是文档中的错误?
限制不
__syncthreads
不能用于条件分支
限制是
请注意,在和给出的示例中,
__syncthreads
不能用于不会被所有线程同时遍历的分支
__syncthreads
没有被依赖于线程ID(或某些每线程数据)的条件所覆盖。在第一种情况下,blockSize
是一个模板参数,它不依赖于线程ID。在第二种情况下,它同样位于if
.
之后。是的,for循环的s > 32
是一个条件,但是它的真值不依赖于线程或它的数据。blockdim.x
对于所有线程都是相同的。所有线程都将执行对s
的完全相同的修改。这意味着所有线程将在其控制流的完全相同的点到达__syncthreads
。这完全没问题。
另一种情况是,不能使用__syncthreads
,这是一个对某些线程为真而对其他线程为假的条件。在这种情况下,您必须关闭所有条件才能使用__syncthreads
。所以不用这个:
if (threadIdx.x < SOME_CONSTANT)
{
operation1();
__syncthreads();
operation2();
}
你必须这样做:
if (threadIdx.x < SOME_CONSTANT)
{
operation1();
}
__syncthreads();
if (threadIdx.x < SOME_CONSTANT)
{
operation2();
}
您给出的两个示例也演示了这一点:在调用__syncthreads
之前关闭依赖于线程id的条件。
相关文章:
- 如果不在窗口 10 中声明名为 openCV 的 openCV namedWindow,QT 图像显示将无法正常工作
- 如果不是多个语句,请使用 if 语句
- 如果不包含 pthread,为什么 GCC 的线程标准库实现会抛出异常?
- C++我们可以取消引用此指针吗?如果是这样,那么如何,如果不是,那为什么?
- 如果不分配内存,我如何能够为变量创建和分配值?
- 如果不初始化结构中的向量,它会自动为空还是具有随机内存位置的值?
- 删除 QGraphicsPixmapItem (如果它已添加到场景中).如果不添加到场景
- 从库中发出信息,而无需运行时成本(如果不需要)
- 可能的模板和constexpr - 如果不兼容
- 如果不是这样,我需要帮助理解这个嵌套的问题
- 如果不需要易失性,为什么 std::atomic 方法会提供易失性重载
- 代码是否有效.如果我想显示第一个元素?如果不是,那么 s.begin() 会返回什么?
- 如果不手动完成,子类是否继承父类的析构函数?
- 如果不是十六进制,则QT从qlineedit中删除字符
- 如果不有效,如何重复用户输入电子邮件
- RE2 语法:如果不共享相同的前缀,则跳过匹配
- 如果不允许使用constexpr,为什么sfinae在上面
- fscanf:如果不返回 EOF,是否可能出现错误或 EOF?
- 如果 OpenCV 的 Cuda 扩展不可用,请使用 CPU 回退
- 如果不能在条件分支中调用 CUDA,如何在 CUDA 中减少__syncthreads?