我需要在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
。
我的错是什么?我必须使用什么样的记忆?
答案 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;