在CUDA内核中填充一个数组或列表,但不是在每个线程中
Fill an array or a list in CUDA kernel but not in every thread
基本上,我的内核中有一个if(),如果条件得到验证,我想在动态列表或数组中存储一个新值。问题是我不能使用threadIdx,因为它不会被填充到每个内核中。
类似于:
__global__ void myKernel(customType *c)
{
int i = threadIdx.x;
//whatever
if(condition)
c->pop(newvalue)
}
事实上,我希望避免使用c[I]=newvalue,因为在最后,我需要检查每个c[I]是否在宿主代码中插入了一个for循环,并正确填充另一个结构。我考虑过推力,但对于我的"简单"问题来说,这似乎有些过头了。
希望你能帮我找到解决办法。
如果我正确理解了你的问题,你有两个选择。
第一种方法是为每个线程预先分配一个输出位置,并且只让一些线程写入其输出。这给你留下了一个有间隙的输出。你可以使用流压缩来消除间隙,这是CUDA中解决的问题-快速谷歌搜索会发现很多选项,Thrust和CUDPP都有压缩功能。
第二种选择是使用全局内存计数器,并让每个线程在使用输出流中的某个位置时原子地递增计数器,因此类似于:
unsigned int opos; // set to zero before call
__global__ void myKernel(customType *c)
{
//whatever
if(condition) {
unsigned int pos = atomicAdd(&opos, 1);
c[pos] = newval;
}
}
如果你有一个开普勒卡,并且预期发出输出的线程数量很小,那么第二种选择可能会更快。如果不是这样的话,流压缩可能是更好的选择。
如果我理解正确,您描述的是流压缩。某些线程(并非所有线程)将创建一个值,并且您希望将这些值存储在一个没有任何间隙的数组中。
实现这一点的一种方法是使用Thrust中提供的流压缩算法(查看此示例)。请注意,这确实需要您分两次执行操作。
如果您是在一个线程块内(而不是整个网格)执行此操作,那么您也可以查看CUB。每个线程将计算一个标志,指示是否要存储值,对标志进行前缀求和,以确定列表中每个线程的偏移量,然后进行存储。
相关文章:
- 如何在不复制列表的情况下将列表传递给线程,同时销毁原始列表
- C++中向量和列表的非写入成员函数的线程安全性
- Xcode:线程1:exc_bad_access(代码= 1,地址= 0x0)在缩短列表时
- 条件_variable和unique_lock如何适用于线程安全列表
- 在为工作线程访问 lambda 中捕获的向量列表中的元素引用时,是否需要互斥锁?
- 慢速插入链接列表需要多线程
- 在C 中共享线程之间的列表
- 可以在构造函数初始值设定项列表中使用标准::线程
- 正确的线程调用语法?错误:没有匹配对 std::thread::thread(<大括号括起来的初始值设定项列表>)
- 列表和多线程环境
- 访问列表项时的 UI 和工作线程同步
- C++ STL 算法(列表排序)OpenMP/多线程实现
- 如何从win32进程中获取线程句柄列表
- 如何从另一个线程更新列表视图
- 在CUDA内核中填充一个数组或列表,但不是在每个线程中
- 如何在迭代列表时最小化互斥锁,同时能够添加来自另一个线程的元素
- 将 rng 的列表存储在 std::array 中以进行多线程处理
- boost线程列表
- C++从线程 ID 列表中查找 GUI 线程
- 从不同的线程同步访问和删除列表中的项