cuda – 零拷贝内存,内存映射文件

我正在尝试创建一个包含uint32_t的映射内存文件,然后将其用作零拷贝固定内存,如下面针对CUDA所示。 我在获取设备指针时获得了cudaErrorInvalidValue ,具有已分配空间并从文件映射内存。 我知道错误消息(来自API)意味着:

这表明传递给API调用的一个或多个参数不在可接受的值范围内。

但我正在努力弄清楚为什么我遇到这个问题……有什么想法吗? 提前致谢。

 #include  #include  #include  #include  #include  #include  … int main(void) { struct stat buf; … uint32_t *data, *dev_data; cudaDeviceProp cuda_prop; cudaGetDeviceProperties(&cuda_prop, 0); if (!cuda_prop.canMapHostMemory) exit(EXIT_FAILURE); cudaSetDeviceFlags(cudaDeviceMapHost); int data_file = open(data_file_name, O_RDONLY); int stat = fstat(sa_file, &buf); int data_file_size = buf.st_size; err = cudaHostAlloc((void**)&data, data_file_size, cudaHostAllocMapped); if (err == cudaErrorMemoryAllocation) exit(EXIT_FAILURE); data = (uint32_t*) mmap(0, data_file_size, PROT_READ, MAP_PRIVATE, data_file, 0); err = cudaHostGetDevicePointer((void**)&dev_data, (void*)data, 0); if (err == cudaErrorMemoryAllocation) { printf("cudaHostGetDevicePointer - Mem Alloc Err\n"); exit(EXIT_FAILURE); } else if (err == cudaErrorInvalidValue) //ERROR HERE. { printf("cudaHostGetDevicePointer - Invalid Val Err\n"); exit(EXIT_FAILURE); } … } 

一个问题是程序的逻辑顺序不正确。 此行为CUDA API提供的data分配值:

 err = cudaHostAlloc((void**)&data, data_file_size, cudaHostAllocMapped); 

然后该行用新的值覆盖该值:

 data = (uint32_t*) mmap(0, data_file_size, PROT_READ, MAP_PRIVATE, data_file, 0); 

此时,CUDA API无法将data值识别为固定内存空间,因此当您调用此数据时:

 err = cudaHostGetDevicePointer((void**)&dev_data, (void*)data, 0); 

您收到错误,因为无法识别data包含的值。

编辑:(基于这个问题 )除了这个问题,似乎如果你将文件处理从只读更改为读写,那么这个过程可以工作(不抛出运行时错误)。 这是一个完整的代码(不包含上述逻辑缺陷),演示了这一点(我之前创建了一个大小为566316字节的test.dat文件):

 $ cat t706.cu #include  #include  #include  #include  #include  #include  #include  int main(void) { struct stat buf; char *dev_data; cudaDeviceProp cuda_prop; cudaGetDeviceProperties(&cuda_prop, 0); if (!cuda_prop.canMapHostMemory) exit(EXIT_FAILURE); cudaSetDeviceFlags(cudaDeviceMapHost); int data_file = open("test.dat", O_RDWR); int stat = fstat(data_file, &buf); int data_file_size = buf.st_size; printf("data_file_size = %d\n", data_file_size); char *data = (char *) mmap(0, data_file_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, data_file, 0); if (data == NULL) { printf("mmap failure\n"); exit(EXIT_FAILURE);} cudaError_t err = cudaHostRegister(data, data_file_size, cudaHostRegisterDefault); if (err != cudaSuccess) { //ERROR HERE. printf("cudaHostRegister fail\n"); exit(EXIT_FAILURE);} err = cudaHostGetDevicePointer((void**)&dev_data, (void*)data, 0); if (err == cudaErrorMemoryAllocation) { printf("cudaHostGetDevicePointer - Mem Alloc Err\n"); exit(EXIT_FAILURE); } else if (err == cudaErrorInvalidValue) { printf("cudaHostGetDevicePointer - Invalid Val Err\n"); exit(EXIT_FAILURE); } } $ nvcc -arch=sm_30 -o t706 t706.cu $ ./t706 data_file_size = 566316 $