cudaHostRegister 在计算能力为 1.1 的 GPU 上返回 cudaErrorInvalidValue

标签 c cuda

我有一个简单的程序,它分配一个 unsigned __int64(堆栈上的 8 个字节),然后尝试使用 cudaHostRegister 在 GPU 上注册该内存。进行此调用的程序部分如下所示:

unsigned __int64 mem;
unsigned __int64 *pMem = &mem;
cudaError_t result;

result = cudaHostRegister(pMem, sizeof(unsigned __int64), cudaHostRegisterMapped);
if(result != cudaSuccess) {
    printf("Error in cudaHostRegister: %s.\n", cudaGetErrorString(result));
    return -1;
}

我在 Visual Studio 2010 Premium 中使用 nvcc 标志 compute_11 和 sm_11 进行编译,并且在我运行 Quadro K1000m 且 cuda 功能版本为 3.0 的笔记本电脑上一切正常。

我最近切换到台式机,尝试使用 GeForce 8600 GT 和 GeForce 9500 GT 运行,它们的 cuda 功能版本均为 1.1。

根据 NVIDIA 的 cudaHostRegister 文档,具有 1.1 及以上 cuda 功能的卡应允许使用 cudaHostRegisterMapped:

cudaHostRegisterMapped: Maps the allocation into the CUDA address space. The device pointer to the memory may be obtained by calling cudaHostGetDevicePointer(). This feature is available only on GPUs with compute capability greater than or equal to 1.1.

经过一些搜索,似乎 cudaHostRegisterMapped 可能需要页面对齐的内存。我认为这可能是我的 3.0 卡和我的 1.1 卡之间的区别,所以我屏蔽了地址以获得页面对齐的地址,并在大小字段中使用页面的大小(4096 字节),如下所示:

unsigned __int64 mem;
unsigned __int64 *pMem = &mem;
unsigned __int64 memAddr = (unsigned __int64)pMem;
cudaError_t result;

pMem = (unsigned __int64 *)(memAddr & 0xFFFFFFFFFFFFF000);

result = cudaHostRegister(pMem, 4096, cudaHostRegisterMapped);
if(result != cudaSuccess) {
    printf("Error in cudaHostRegister: %s.\n", cudaGetErrorString(result));
    return -1;
}

此代码也适用于我的 3.0 卡,但在我的 1.1 卡上失败,结果与之前相同。 cudaHostRegister 函数返回错误 cudaErrorInvalidValue,表明:

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

我无法找到更多有关为什么此功能可能会像这样失败的信息。感谢任何人可以提供的任何帮助。

[编辑] 根据 talonmies 的响应,我验证了至少我的一张卡(9500 GT,我没有在 8600 GT 上运行它)根据 SDK 附带的 NVIDIA deviceQuery 可执行文件支持内存映射。

最佳答案

映射内存在一些计算能力为 1.1 的设备上受支持,但并非全部。 MCP79 系列集成芯片组(如 Ion 和 9300M/9400M)支持映射内存。但是,较旧的计算能力 1.1 设备(如 8600GT 和 9500GT)不支持映射内存。

您可以使用 cudaGetDeviceProperties API 调用以编程方式检查这一点; canMapHostMemory 会告诉您给定设备是否支持映射内存。

关于cudaHostRegister 在计算能力为 1.1 的 GPU 上返回 cudaErrorInvalidValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12301772/

相关文章:

c - 何时在 C 中将 '*' 放在指针之前

frameworks - CUDA 和 OpenCL 之前的 GPGPU

cuda - GPGPU-CUDA : global store efficiency

c - 如何用指针交换项目

Python RGB 数组到 HSL 并返回

cuda - 推力:使用device_ptr时如何获取copy_if函数复制的元素数量

python - 与默认计数器相比,GPU 上的计数器慢得要命?

使用 CUDA 的 matlab if 语句

c - 为什么这个函数不会陷入无限循环?

C 将字符一一追加到字符数组中