CUDA中的地址错位

时间:2016-05-19 12:20:25

标签: cuda alignment gpu gpgpu nvidia

任何人都可以告诉我CUDA内核中的以下代码有什么问题:

__constant__ unsigned char MT[256] = {
    0xde, 0x6f, 0x6f, 0xb1, 0xde, 0x6f, 0x6f, 0xb1, 0x91, 0xc5, 0xc5, 0x54, 0x91, 0xc5, 0xc5, 0x54,....};

typedef unsinged int U32;

__global__ void Kernel (unsigned int  *PT, unsigned int  *CT, unsigned int  *rk)
{

    long int i;
    __shared__ unsigned char sh_MT[256];    

    for (i = 0; i < 64; i += 4)
        ((U32*)sh_MT)[threadIdx.x + i] = ((U32*)MT)[threadIdx.x + i];

    __shared__ unsigned int sh_rkey[4];
    __shared__ unsigned int sh_state_pl[4];
    __shared__ unsigned int sh_state_ct[4];

    sh_state_pl[threadIdx.x] = PT[threadIdx.x];
    sh_rkey[threadIdx.x] = rk[threadIdx.x];
    __syncthreads();


    sh_state_ct[threadIdx.x] = ((U32*)sh_MT)[sh_state_pl[threadIdx.x]]^\
    ((U32*)(sh_MT+3))[((sh_state_pl[(1 + threadIdx.x) % 4] >> 8) & 0xff)] ^ \
    ((U32*)(sh_MT+2))[((sh_state_pl[(2 + threadIdx.x) % 4] >> 16) & 0xff)] ^\
    ((U32*)(sh_MT+1))[((sh_state_pl[(3 + threadIdx.x) % 4] >> 24) & 0xff )];


    CT[threadIdx.x] = sh_state_ct[threadIdx.x];
}

在这行代码中,

((U32*)(sh_MT+3))......

CUDA调试器给出了错误消息: 地址错位

如何修复此错误?

我在MVSC中使用CUDA 7,我使用1个Block和4个线程来执行内核函数,如下所示:

__device__ unsigned int *state;
__device__ unsigned int *key;
__device__ unsigned int *ct;
.
.
main()
{
cudaMalloc((void**)&state, 16);
cudaMalloc((void**)&ct, 16);
cudaMalloc((void**)&key, 16);
//cudamemcpy(copy some values to => state , ct, key);   
Kernel << <1, 4 >> >(state, ct, key); 
}

请记住,我不能改变我的“MT Table”类型。 提前感谢任何建议或答案。

1 个答案:

答案 0 :(得分:6)

正如错误消息所示,指针未与处理器所需的边界对齐。

来自CUDA Programming Guide, section 5.3.2

  

全局存储器指令支持读取或写入大小等于1,2,4,8或16字节的字。当且仅当数据类型的大小为1,2,4,8或16字节并且数据自然地存在时,对驻留在全局存储器中的数据的任何访问(通过变量或指针)编译成单个全局存储器指令。对齐(即,其地址是该大小的倍数)。

这是调试器试图告诉你的:基本上,你不应该从未在32位边界对齐的地址取消引用指向32位值的指针。

您可以(U32*)(sh_MT)(U32*)(sh_MT+4)正常,但不能(U32*)(sh_MT+3)或等。{/ p>

您可能需要单独读取字节并将它们连接在一起。