cuda记忆复制力对齐

时间:2016-04-19 11:21:04

标签: cuda memory-alignment

我写了一个测试来说明我的问题,代码尝试将16个字节复制到非4字节对齐的内存,但 dest 会自动修改

#include <cuda.h>
#include <cuda_runtime.h>
#include <stdio.h>

__global__
void Copy128(char *dest,const char *src)
{
    ((int*)dest)[0]=((int*)src)[0];
    ((int*)dest)[1]=((int*)src)[1];
    ((int*)dest)[2]=((int*)src)[2];
    ((int*)dest)[3]=((int*)src)[3];
}
__global__
void fill_src(char *src)
{
    for(int i=0; i<16; i++)
        src[i] = i+1; // starts from 1
}

int main()
{
    char* dest;
    cudaMalloc(&dest, 17);

    char* src;
    cudaMalloc(&src, 16);

    fill_src<<<1, 1>>>((char*)src); // fill some value for debugging

    // copy to dest+1 which is not aligned to 4
    Copy128<<<1, 1>>>(dest + 1, src);

    getchar();
}

如图所示调试VS2013中的代码,目标内存为0x40A8000 1 ,但实际上它复制到0x40A8000 0 enter image description here

如果 dest 未与4字节对齐,则会自动修改 dest 。并且它被默默地修改,我花了几个小时来发现这个错误。

我知道最好使用良好对齐的内存,但我正在编写一些rar解压缩程序,解压缩一些字节然后连接一些字节,它不能总是对齐。

我想我会在像Copy256这样的函数中使用uint64。记忆是强制对齐的这种正常行为吗?任何可以关闭此功能的编译标志?或者我应该逐个复制字节?

环境:CUDA 6.5,Win7-32​​bit,VS2013

1 个答案:

答案 0 :(得分:4)

- 内存强行对齐这是正常行为吗? 是:引自here,&#34;驻留在全局内存中或由驱动程序或运行时API中的一个内存分配例程返回的变量的任何地址始终对齐至少256个字节&#34;。

任何可以关闭此功能的编译标志? 我猜不是,这可能与硬件有关

或者我应该逐个复制字节吗? 如果您处理(非常)未对齐的内存,它是您避免错位存储的唯一选择(如上所述)。 但是,您应该尝试在内存操作对齐时检测(在编译时或运行时),然后使用您手头最宽的加载/存储(int4导致ldg指令,这将为您提供更好的带宽)