简体   繁体   English

在CUDA中置换数组的元素

[英]Permuting the elements of an array in CUDA

I need to permute the elements of an array (row of a matrix) with parallel programming in CUDA. 我需要使用CUDA中的并行编程来置换数组(矩阵行)的元素。

My attempt is the following 我的尝试如下

__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();
}           

The above approach doesn't work. 上面的方法行不通。

What I want: 我想要的是:

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

My output is: 我的输出是:

**6E 90 4C 6E**

B[4] and B[7] have same value. B[4]B[7]具有相同的值。 I think that, in the case of parallel processing, I should be able to avoid the temporary storage: int TEMP = B[4]; B[7]=TEMP 我认为,在并行处理的情况下,我应该能够避免临时存储: int TEMP = B[4]; B[7]=TEMP int TEMP = B[4]; B[7]=TEMP . int TEMP = B[4]; B[7]=TEMP

What is my fault? 我怎么了 What kind of memory I have to use? 我必须使用哪种内存?

I would suggest using atomic operations to avoid the race condition whose effect you are observing. 我建议使用原子操作来避免您观察到的竞争状态。 As atomic operation, you can use atomicCAS . 作为原子操作,可以使用atomicCAS The approach below will work for any grid size. 下面的方法适用于任何网格大小。 As an alternative approach, you can define a new, temporary array (as you mentioned in your post) and avoid atomic operations. 作为一种替代方法,您可以定义一个新的临时数组(如您在帖子中所提到的),并避免原子操作。

Here is the code using CUDA atomics. 这是使用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();

} 

You are modifying data in global while other are reading so the output is wrong. 您正在全局修改数据,而其他正在读取,因此输出错误。 You should do something like that. 你应该做类似的事情。 Like you read your data and once every thread has the data registered you write into the new element of your array. 就像您读取数据一样,一旦每个线程都注册了数据,就可以将其写入数组的新元素。 Like: 喜欢:

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

__syncthreads();

dataB[indexSwap+tid] = local;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM