Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CUDA统一内存和Windows 10_Windows_Cuda_Unified Memory - Fatal编程技术网

CUDA统一内存和Windows 10

CUDA统一内存和Windows 10,windows,cuda,unified-memory,Windows,Cuda,Unified Memory,在使用cudamalocmanaged()分配内部包含数组的结构数组时,即使我有足够的可用内存,也会出现“内存不足”的错误。下面是一些复制我的问题的代码: #include <iostream> #include <cuda.h> #define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } inline void gpuAssert(cudaError_t code, const char *file

在使用cudamalocmanaged()分配内部包含数组的结构数组时,即使我有足够的可用内存,也会出现“内存不足”的错误。下面是一些复制我的问题的代码:

#include <iostream>
#include <cuda.h>

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess) 
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}

#define N 100000
#define ARR_SZ 100

struct Struct
{
    float* arr;
};

int main()
{
    Struct* struct_arr;

    gpuErrchk( cudaMallocManaged((void**)&struct_arr, sizeof(Struct)*N) );
    for(int i = 0; i < N; ++i)
        gpuErrchk( cudaMallocManaged((void**)&(struct_arr[i].arr), sizeof(float)*ARR_SZ) ); //out of memory...

    for(int i = 0; i < N; ++i)
        cudaFree(struct_arr[i].arr);
    cudaFree(struct_arr);

    /*float* f;
    gpuErrchk( cudaMallocManaged((void**)&f, sizeof(float)*N*ARR_SZ) ); //this works ok
    cudaFree(f);*/

    return 0;
}
#包括
#包括
#定义gpuerchk(ans){gpuAssert((ans),_文件_,_行__)}
内联void gpuAssert(cudaError\u t代码,const char*文件,int行,bool abort=true)
{
如果(代码!=cudaSuccess)
{
fprintf(标准,“GPUassert:%s%s%d\n”,cudaGetErrorString(代码)、文件、行);
如果(中止)退出(代码);
}
}
#定义N 100000
#定义ARR_SZ 100
结构
{
浮动*arr;
};
int main()
{
结构*Struct_arr;
gpuerchk(cudaMallocManaged((void**)和struct_arr,sizeof(struct)*N));
对于(int i=0;i
当我调用一次cudamalocmanaged()来分配单个内存块时,似乎没有问题,正如我在最后一段注释代码中所示。 我有一个GeForce GTX 1070 Ti,我使用的是Windows 10。一位朋友试图在一台装有Linux的PC上编译相同的代码,但它工作正常,而在另一台装有Windows 10的PC上也有同样的问题。WDDM TDR已停用。
任何帮助都将不胜感激。谢谢。

有一个分配粒度

这意味着,如果您要求1个字节或400个字节,实际使用的是409665536个字节。因此,一堆非常小的分配实际上会以比您根据请求的分配大小预测的更快的速度使用内存。解决方案是不进行非常小的分配,而是分配更大的块

这里还有一种替代策略,即将您的分配平坦化,并为每个阵列从中分割出碎片:

#include <iostream>
#include <cstdio>

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess)
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}

#define N 100000
#define ARR_SZ 100

struct Struct
{
    float* arr;
};

int main()
{
    Struct* struct_arr;
    float* f;

    gpuErrchk( cudaMallocManaged((void**)&struct_arr, sizeof(Struct)*N) );
    gpuErrchk( cudaMallocManaged((void**)&f, sizeof(float)*N*ARR_SZ) );
    for(int i = 0; i < N; ++i)
        struct_arr[i].arr = f+i*ARR_SZ;
    cudaFree(struct_arr);
    cudaFree(f);

    return 0;
}
当我使用该代码编译调试项目,并在带有RTX 2070 GPU(8GB内存,与GTX 1070 Ti相同)的windows 10桌面上运行该项目时,我得到以下输出:

Microsoft Windows [Version 10.0.17763.973]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Users\Robert Crovella>cd C:\Users\Robert Crovella\source\repos\test12\x64\Debug

C:\Users\Robert Crovella\source\repos\test12\x64\Debug>test12
Free: 7069866393 total: 8589934592
Free: 516266393 total: 8589934592

C:\Users\Robert Crovella\source\repos\test12\x64\Debug>test12
Free: 7069866393 total: 8589934592
Free: 516266393 total: 8589934592

C:\Users\Robert Crovella\source\repos\test12\x64\Debug>
  • 请注意,在我的机器上,在100000次分配之后,报告的可用内存只剩下0.5GB。因此,如果出于任何原因,您的8GB GPU开始时可用内存较少(完全可能),您可能会遇到内存不足错误,即使我没有

  • 分配粒度的计算如下:

    7069866393 - 516266393 / 100000 = 65536 bytes per allocation(!)
    
    因此,在我的机器/测试设置中,我之前估计的每个分配4096字节的大小至少相差1个数量级

  • 分配粒度可能根据以下情况而变化:

    • windows或linux
    • 波分复用器
    • x86或Power9
    • 托管与普通
      cudamaloc
    • 可能的其他因素(例如CUDA版本)
    所以我给未来读者的建议是,不要假设每次分配的最小值总是65536字节


  • 谢谢你的回答,我不知道这个“粒度”,所以需要记住。即便如此,在我发布的示例中,我分配了大约40 mb的内存,如果每个调用需要大约4 kb,那么100k调用应该需要大约400 mb,这还不足以用这个GPU耗尽内存,那么这怎么可能呢?也许粒度大于4096字节?那只是对尺寸的猜测。它没有出版。您可以使用
    cudaMemGetInfo()
    自己估计粒度,似乎就是这样。我已经编辑了我的答案。非常有趣!虽然当我试图估计我这方面的粒度时,似乎还有其他事情在进行。在
    cudamalocmanaged()
    之后使用
    cudaMemGetInfo()
    时,GPU内存保持不变。所以我猜它被分配到其他地方了?你现在是在linux上还是在windows上运行这个测试?
    7069866393 - 516266393 / 100000 = 65536 bytes per allocation(!)