cuda内存复制强制对齐

cuda内存复制强制对齐,cuda,memory-alignment,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]=((in

我编写了一个测试来说明我的问题,代码试图将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();
}
#包括
#包括
#包括
__全球的__
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];
}
__全球的__
空白填充(字符*src)
{

对于(int i=0;i-内存是强制对齐的,这是正常行为吗? 是:引自“驻留在全局内存中的变量的任何地址或由驱动程序或运行时API的内存分配例程之一返回的变量的任何地址始终与至少256字节对齐”

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

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

当我运行您的示例代码时,我在Copy128内核中遇到了一个非法写入错误,因为未对齐的内存访问,这正是应该发生的。我不明白您在这里想说的是什么,除了在x86 CPU上,GPU上的所有内存访问必须自然对齐,即与访问大小对齐,例如4-字节访问必须与4字节边界对齐。因此,在GPU上,这种内存访问对齐是功能正确性所必需的,而不仅仅是x86上的性能。CUDA文档中提到了这一点。对于未对齐的副本,您不需要完全逐字节复制较大的对象,只需对最终情况使用窄访问,并使用大批量传输的宽拷贝。