cudaMemPrefetchAsync 上的设备序号无效

Reg*_*lez 1 cuda

我正在 Windows 10 和 CUDA 9.2 上的 GeForce 1080 Ti (Pascal) 上运行玩具 CUDA 示例。

目标是测试CPU 的cudaMemPrefetchAsync ,因为它应该可以工作。

但是,我在该特定行上收到 CUDA 错误(无效的设备序号)。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <cstdio>
#include <cstdlib>

void fill(int* a, int val, int N) {
    for (int k = 0; k < N; ++k) {
        a[k] = val;
    }
}

__global__ void add(int* a, int* b, int N)
{
    for (int i = threadIdx.x + blockIdx.x * blockDim.x; i < N; i += blockDim.x * gridDim.x) {
        a[i] += b[i];
    }
}

inline void check(cudaError_t err, const char* file, int line) {
    if (err != cudaSuccess) {
        ::fprintf(stderr, "ERROR at %s[%d] : %s\n", file, line, cudaGetErrorString(err));
        abort();
    }
}

#define CUDA_CHECK(err) do { check(err, __FILE__, __LINE__); } while(0)

int main()
{
    int deviceId;
    CUDA_CHECK(cudaGetDevice(&deviceId));
    const int N = 1024*1024*32;
    int *a, *b;
    CUDA_CHECK(cudaMallocManaged(&a, N * sizeof(int)));
    CUDA_CHECK(cudaMallocManaged(&b, N * sizeof(int)));

    CUDA_CHECK(cudaMemPrefetchAsync(a, N * sizeof(int), cudaCpuDeviceId)); // program breaks here
    CUDA_CHECK(cudaMemPrefetchAsync(b, N * sizeof(int), cudaCpuDeviceId));
    fill(a, 1, N);
    fill(a, 2, N);

    CUDA_CHECK(cudaMemPrefetchAsync(a, N * sizeof(int), deviceId));
    CUDA_CHECK(cudaMemPrefetchAsync(b, N * sizeof(int), deviceId));

    add<<<32, 256>>>(a, b, N);

    CUDA_CHECK(cudaGetLastError());
    CUDA_CHECK(cudaDeviceSynchronize());

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是硬件/驱动程序/操作系统的限制吗?我可以简单地忽略该错误吗?

tal*_*ies 5

这是硬件/驱动程序/操作系统的限制吗?

是的,是后者。引用自文档

采用 SM 架构 6.x 或更高版本(Pascal 级或更高版本)的 GPU 提供额外的统一内存功能,例如本文档中概述的按需页面迁移和 GPU 内存超额订阅。请注意,目前这些功能在 Linux 操作系统上受支持。

因此,目前 Windows 不支持异步页面迁移,这也是您在尝试启用它时收到错误的原因。