2012-04-25 64 views
1

我在使用CUDA对数组进行并行化时遇到了麻烦。CUDA并行化

因此,例如,如果我们有包含数字数组M(1,2,3,4,5)

如果我是除去在阵列中的数字2和移位一切到左侧,其中M [1] = M [2],M [2] = M [3],M [3] = M [4],得到的阵列可以是(1,3,4,5,5)

]

而我的问题是我们怎么能在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只是一个从二维数组转换而来的一维数组...然而,我的代码不工作...我认为竞争条件是问题。

谢谢!

+3

流压实是在GPU上一个解决的问题。您可以使用一系列强大的现成CUDA实现,包括[C](CUDA)工具包中提供的[thrust](http://code.google.com/p/thrust/)实现,年份。你为什么不使用其中之一? – talonmies 2012-04-25 20:12:54

回答

1

作为talonmies在他的评论中指出,这种事情被称为“溪流压实”。这里是你如何与推力做到这一点:

#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