C++ CUDA同时使用atomicAdd和atomicCAS实现价值重塑
我有一个CUDA内核,其中输入是一个全局数组,输出是另一个大小相同的数组。我试图将一个数组中的值重新映射到另一个数组中,条件是它们的一个相邻数组的值。伪代码如下所示:C++ CUDA同时使用atomicAdd和atomicCAS实现价值重塑,c++,cuda,atomic,C++,Cuda,Atomic,我有一个CUDA内核,其中输入是一个全局数组,输出是另一个大小相同的数组。我试图将一个数组中的值重新映射到另一个数组中,条件是它们的一个相邻数组的值。伪代码如下所示: remap(int* in, int* out, int* counter) { idx = threadIdx q = index calculated based on idx if ( in[q] > 0 ) { newValue = in[q]; } else {
remap(int* in, int* out, int* counter) {
idx = threadIdx
q = index calculated based on idx
if ( in[q] > 0 ) {
newValue = in[q];
} else {
newValue = *counter;
*counter += 1;
in[q] = newValue;
}
out[idx] = newValue;
}
此代码的问题是多个线程将尝试同时检查和更新q
索引的值。真正接近我想要实现的代码是:
__global__
void remap(int* in, const int* out, int* counter) {
idx = threadIdx;
q = index calculated based on idx;
newValue = atomicCAS(&in[q], 0, atomicAdd(counter, 1));
out[idx] = newValue;
}X
根据文档,上面的atomicCAS
是否计算(in[q]==0)?newCounter:in[q]
并根据需要存储结果。问题是无论条件是否满足,newCounter=counter+1
都会得到更新。我在寻找类似的东西:
(in[q] == 0) ? in[q] = (counter += 1) : in[q]
我确实意识到上述语法不正确,只是想说明我正试图同时原子化两个更新操作,计数器
的增量和[q]中的的更新,但前提是满足一个条件,否则我不想要任何一个
希望问题相当清楚。现在的问题是,这是否可行?如果满足条件,则对两个缓冲区进行原子更新,否则对缓冲区的值进行原子更新。或者这在CUDA中是不可行的,我应该去别处看看。关键部分可能是您唯一的实际选择,它很难纠正,并且具有有限的可扩展性。您无法对内存中的两个独立位置进行原子更新。但是,通过一点数据重组,您可能可以使用a来更新2个变量。