gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 15:35:27 31 4
gpt4 key购买 nike

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

This indicates that one or more of the parameters passed to the API call is not within an acceptable range of values.

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

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>



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);

此时,data 的值不再被 CUDA API 识别为固定内存空间,因此当您调用它时:

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

你得到一个错误,因为包含在 data 中的值不被识别。

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

$ cat t706.cu
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>

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 == MAP_FAILED) {
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
$

关于cuda - 零拷贝内存,内存映射文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29518875/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com