我写了一个测试来说明我的问题,该代码尝试将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。
问题是,如果dest与4字节不对齐,它将自动被修改。而且它经过了无提示的修改,我花了数小时才找到此错误。
我知道最好使用对齐良好的内存,但是我正在编写一些rar解压缩程序,先解压缩一些字节,然后再合并一些字节,但它不能总是对齐的。
我想我会在像Copy256这样的函数中使用uint64。记忆是强制对齐的这种正常行为吗?是否有任何可以关闭此功能的编译标志?还是我应该一一复制字节?
环境:CUDA 6.5,Win7-32bit,VS2013
-记忆是强制对齐的这种正常行为吗?是:从这里引用:“驻留在全局内存中或由驱动程序或运行时API的内存分配例程之一返回的变量的任何地址始终至少对齐256个字节”。
是否有任何可以关闭此功能的编译标志?我想不是,这可能与硬件有关
还是我应该一一复制字节?如果您处理(非常)未对齐的内存,那么这是避免未对齐存储的唯一选择(如上所述)。但是,您应该尝试(在编译时或在运行时)检测内存操作是否对齐,然后使用手边最宽的加载/存储(int4导致ldg指令),这将为您提供更好的带宽方法)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句