Windows 10上来自多个进程的cudaMemGetInfo行为不一致

时间:2019-06-13 16:07:03

标签: windows cuda gpu

当同时使用CUDA(v10.1)运行两个(或多个)程序时,我发现cudaMemGetInfo的行为存在重大差异。我有两张GTX 2080显卡(每张都有大约8GB的RAM)。在单个过程中,cudaMemGetInfo的行为在很大程度上是有意义的-分配后报告为可用的内存量恰好是先前可用的数量减去分配的数量。但是,如果一个进程分配了一个大数组,然后另一个进程稍后再调用cudaMemGetInfo,则返回值表明所有内存仍然可用。这是我为测试此应用而制作的一个简单控制台应用程序中的示例:

  
    

您要使用哪个GPU设备?     
0     
您已选择设备0     
此设备总共有8589934592字节可用。     
7033.39 MB的剩余空间。输入新的阵列大小(以MB为单位),或输入0退出。     
3000     
4033.35 MB的剩余空间。输入新的数组大小(以MB为单位),或输入0退出。

  

现在,打开此控制台并打开另一个控制台以同时运行同一程序,我得到以下信息:

  
    

您要使用哪个GPU设备?     
0     
您已选择设备0     
此设备总共有8589934592字节可用。     
7033.39 MB的剩余空间。输入新的数组大小(以MB为单位),或输入0退出。

  

然后它将允许我cudaMalloc高达7033.39MB,而不会崩溃或返回cuda内存错误! 但是如上所述,行为并不完全一致-有时可以看到分配的数组,有时却看不到(有趣的是,在运行两个完全不同的程序而不是同一程序的两个实例时,该行为似乎更常见) 。我注意到在任务管理器中,在性能下,每张卡都有“专用”和“共享” GPU内存,并且两者的总和始终匹配(在一定程度上,Windows会为自己保留一块块,这是许多其他人抱怨的)关于)我从所有流程中请求的总金额。

由于我似乎无法使它崩溃或引发错误,尽管显然以某种方式获取了比单张卡上实际可用的GPU内存更多的内存,所以我很犹豫在Windows中将其称为“错误” ,但是这非常令人困惑和不便(我沿着这条路走了,因为我正在玩专有的深度学习代码,并希望能够运行两个独立的实例,根据可用内存自动检测要使用的卡;显然,此问题阻止了用作误导性的cudaMemGetInfo输出有时会导致我的代码在一张卡上分配两个DNN,而不是在每张卡上分配两个DNN)。另外,我想知道CUDA例程是否可以在“共享” GPU内存上真正地像在“专用” GPU内存上一样快地运行...

是否有人对Windows正在使用此神秘的“共享GPU内存”以及/或如何解决此问题有任何见解,以便始终可以识别出具有最大实际可用内存量的卡? >

这是我用来探究此行为的控制台应用程序的代码:

int main()
{
    size_t iMem = 0;
    size_t szBytesRemaining, szBytesTotal;
    std::cout << "Which GPU device would you like to use?\n";
    int iDevice = -1;
    std::cin >> iDevice;
    std::cout << "You have selected device " << iDevice << "\n";
    cudaSetDevice(iDevice);
    cudaMemGetInfo(&szBytesRemaining, &szBytesTotal);
    std::cout << "This device has a total of " << szBytesTotal << " bytes available.\n";
    int *iTestArray = nullptr;
    while (true)
    {
        cudaMemGetInfo(&szBytesRemaining, &szBytesTotal);
        std::cout << float(szBytesRemaining) / 1e6 << " MB of space left. Enter a new array size (in MB), or 0 to exit.\n";
        std::cin >> iMem;

        cudaFree(iTestArray);
        if (iMem <= 0)
            break;
        cudaError_t errTest = cudaMalloc(&iTestArray, iMem*size_t(1000000));
        if (errTest != cudaSuccess)
            std::cout << "Error! Code = " << (int)errTest << "\n";
    }
}

0 个答案:

没有答案