我在使用CUDA对数组进行并行化时遇到了麻烦。
所以,例如,如果我们有一个包含数字的数组M(1,2,3,4,5)
如果我要移除数组中的数字2并将所有内容移到左侧, 得到的数组将是(1,3,4,5,5)
其中M [1] = M [2],M [2] = M [3],M [3] = M [4]
我的问题是我们如何在cuda中并行执行此操作?因为当我们平行时 可能存在竞争条件,其中数字2(M [1])可能不是第一个 首先,如果M [2]是第一个移位的,那么结果阵列就会变成 (1,4,4,5,5)。有没有办法处理这个?我对cuda相当新,所以我 不知道该怎么做......
我目前的代码如下:
__global__ void gpu_shiftSeam(int *MCEnergyMat, int *seam, int width, int height, int currRow)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
int index = i+width*j;
if(i < width && j <height)
{
//shift values of -1 to the side of the image
if(MCEnergyMat[i+width*j] == -1)
{
if(i+1 != width)
MCEnergyMat[index] = MCEnergyMat[index+1];
}
if(seam[j] < i)
{
if(i+1 != width)
MCEnergyMat[index] = MCEnergyMat[index+1];
}
}
}
其中seam[i]
包含我想在数组中删除的索引。而MCEnergyMat
只是一个从二维数组转换而来的一维数组...但是,我的代码不起作用......我相信竞争条件就是问题。
谢谢!
答案 0 :(得分:1)
正如talonmies在评论中指出的那样,这种事情被称为“流压缩”。以下是你如何使用Thrust做到这一点:
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/remove.h>
#include <iostream>
int main()
{
int data[5] = {1,2,3,4,5};
thrust::device_vector<int> d_vec(data, data + 5);
// new_end points to the end of the sequence after 2 has been thrown out
thrust::device_vector<int>::iterator new_end =
thrust::remove(d_vec.begin(), d_vec.end(), 2);
// erase everything after the new end
d_vec.erase(new_end, d_vec.end());
// prove that it worked
thrust::host_vector<int> h_vec = d_vec;
std::cout << "result: ";
thrust::copy(h_vec.begin(), h_vec.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
结果如下:
$ nvcc test.cu -run
result: 1 3 4 5