我有以下示例代码。
struct Data
{
float* arr_f_ptr;
int* arr_i_ptr;
short* arr_s_ptr;
size_t arr_f_size;
size_t arr_f_size_bytes;
size_t arr_i_size;
size_t arr_i_size_bytes;
size_t arr_s_size;
size_t arr_s_size_bytes);
};
void processing (Data &d)
{
// call some kernels on d.arr_f_ptr, d.arr_i_ptr, d.arr_s_ptr
// using cufftExecR2C on d.arr_f_ptr, d.arr_i_ptr, d.arr_s_ptr
}
Data d;
// filling the sizes of the arrays
d.arr_f_size = ....;
d.arr_f_size_bytes = d.arr_f_size * sizeof(float);
d.arr_i_size = ....;
d.arr_i_size_bytes = d.arr_i_size * sizeof(int);
d.arr_s_size = ....;
d.arr_s_size_bytes = d.arr_s_size * sizeof(short);
size_t total_size_bytes = arr_f_size_bytes + arr_i_size_bytes + arr_s_size_bytes;
// allocate device memory
char *device_pointer;
gpuErrchk(cudaMalloc((void**)&device_pointer, total_size_bytes));
// map memory to pointers
size_t index = 0;
d.arr_f_ptr = (float*)&device_pointer[index]; index += d.arr_f_size_bytes;
d.arr_i_ptr = (int*)&device_pointer[index]; index += d.arr_i_size_bytes;
d.arr_s_ptr = (short*)&device_pointer[index];
// copy data from host to arrays in data
....
// call processing function
processing(d);
// deallocate
....
我尝试在设备内存中分配线性数组,然后将三个不同的数组(不同类型)映射到此线性数组上的连续位置。
问题是当在处理函数中调用内核时,我得到未指定的启动失败错误。当我在这个数据上使用cufftExecR2C时,我得到无效的设备内存指针错误。
在处理功能中,我从主机复制了输入数据(在d中)并进行了检查。它似乎完全正确并匹配主机中的数据。因此,我知道正确完成了对主机的复制,并且设备内存包含正确的数据。
那么,我到这儿出现这种错误的原因是什么? 任何帮助都非常感谢 感谢
答案 0 :(得分:2)
这是对齐问题,你可以使用3 cudaMalloc
分别为每个数组分配空间。
驻留在全局内存中或由一个返回的变量的任何地址 来自驱动程序或运行时API的内存分配例程是 始终对齐至少256个字节。
http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory-accesses
答案 1 :(得分:1)
你忘了对齐。它可以是字节,字,双字等。
因此,数据的大小可以根据它改变。
sizeof(Data)可能不是sizeof(每个成员)的总和
按代码检查 (arr_f_size_bytes + arr_i_size_bytes + arr_s_size_bytes == sizeof(Data)) 如果它是假的,那你就会错位。