在CUDA中置换数组的元素

时间:2014-04-23 09:22:18

标签: arrays cuda parallel-processing element swap

我需要在CUDA中使用并行编程来置换数组的元素(矩阵的行)。

我的尝试是以下

__global__ void CudaProcessingKernel(int *dataA) 
{

    int bx = blockIdx.x;  
    int tx = threadIdx.x;  
    int tid = bx * XTHREADS + tx;  

    if(tid< 16)     // matrix 4x4
    {

        if(tid==4)  dataB[tid]=dataB[5];
        if(tid==5)  dataB[tid]=dataB[6];
        if(tid==6)  dataB[tid]=dataB[7];
        if(tid==7)  dataB[tid]=dataB[4];
    }

    __syncthreads();
}           

上述方法不起作用。

我想要的是什么:

input B[1][]  =  **EC 6E 4C 90** => output **6E 4C 90 EC**

我的输出是:

**6E 90 4C 6E**

B[4]B[7]具有相同的值。我认为,在并行处理的情况下,我应该能够避免临时存储:int TEMP = B[4]; B[7]=TEMP

我的错是什么?我必须使用什么样的记忆?

2 个答案:

答案 0 :(得分:1)

我建议使用原子操作来避免你正在观察其影响的竞争条件。作为原子操作,您可以使用atomicCAS。以下方法适用于任何网格大小。作为替代方法,您可以定义一个新的临时数组(正如您在帖子中提到的那样)并避免原子操作。

以下是使用CUDA原子的代码。

#include <stdio.h>

#define N 10

__global__ void swap_kernel(int* data) {

    int tid = blockIdx.x*blockDim.x + threadIdx.x;

    if (tid < N) { atomicCAS(&data[tid], data[tid], data[(tid+1) % N]); }

}

void main() {

    int* h_vec = (int*) malloc(N*sizeof(int));
    int* d_vec; cudaMalloc((void**)&d_vec,N*sizeof(int));

    for (int i=0; i<N; i++) h_vec[i] = i;

    cudaMemcpy(d_vec,h_vec,N*sizeof(int),cudaMemcpyHostToDevice);

    swap_kernel<<<2,8>>>(d_vec);

    cudaMemcpy(h_vec,d_vec,N*sizeof(int),cudaMemcpyDeviceToHost);

    for (int i=0; i<N; i++) printf("%i %i\n",i,h_vec[i]);

    getchar();

} 

答案 1 :(得分:0)

您正在修改全局数据而其他数据正在读取,因此输出错误。你应该做那样的事情。就像你读取你的数据一样,一旦每个线程都注册了数据,你就会写入数组的新元素。像:

[..]
int local = dataB[indexToSwap+tid];

__syncthreads();

dataB[indexSwap+tid] = local;