windows - 为什么 OpenGL 和 CUDA 上下文内存贪婪?

标签 windows opengl cuda operating-system cuda-context

我开发的软件通常包括 OpenGL 和 Nvidia CUDA SDK。最近,我也开始寻找优化运行时内存占用的方法。我注意到以下内容(调试和发布版本仅相差 4-7 Mb):
应用程序启动 - 小于 1 MB 全部的
OpenGL 4.5 上下文创建(+ GLEW 加载程序初始化)- 45 MB 全部的
CUDA 8.0 上下文(驱动 API)创建 114 MB 全部的。
如果我在“ headless ”模式下创建 OpenGL 上下文,则 GL 上下文会少用 3 Mb,这可能会用于默认帧缓冲区分配。这是有道理的,因为窗口大小是 640x360。
所以在 OpenGL 和 CUDA 上下文启动后,进程已经消耗了 114 MB .
现在,我对在 GL 和 CUDA 上下文创建期间发生在幕后的操作系统特定的东西没有深入的了解,但是 GL 的 45 Mb 和 CUDA 的 68 对我来说似乎很多。我知道通常有几兆字节用于系统帧缓冲区、函数指针(可能大部分分配发生在驱动程序端)。但是仅使用“空”上下文达到 100 Mb 以上看起来太多了。
我想知道:

  • 为什么 GL/CUDA 上下文创建会消耗如此大量的内存?
  • 有没有办法优化它?

  • 被测系统设置:
    Windows 10 64 位。 NVIDIA GTX 960 GPU(驱动程序版本:388.31)。 8 Gb 内存。 Visual Studio 2015,64 位 C++ 控制台项目。
    我使用 Visual Studio 内置的诊断工具 -> 进程内存部分测量内存消耗。
    更新
    按照 datenwolf 的建议,我尝试了 Process Explorer。这是我得到的屏幕截图(底部标记为黄色的我的过程):
    enter image description here
    我将不胜感激有关该信息的一些解释。我总是在“VS 诊断工具”窗口中查看“私有(private)字节”。但在这里我还看到“工作集”、“WS Private”等。哪一个正确显示了我的进程当前使用了多少内存? 281,320K 看起来太多了,因为正如我上面所说,启动时的进程什么都不做,而是创建 CUDA 和 OpenGL 上下文。

    最佳答案

    部分答案:这是一个特定于操作系统的问题;在 Linux 上,CUDA 占用 9.3 MB。

    我在 GNU/Linux 上使用 CUDA(不是 OpenGL):

  • CUDA 版本:10.2.89
  • 操作系统发行版:Devuan GNU/Linux Beowulf (~= Debian Buster without systemd)
  • 内核:Linux 5.2.0
  • 处理器:英特尔 x86_64

  • 为了检查 CUDA 在创建上下文时使用了多少内存,我运行了以下 C 程序(它还检查了上下文销毁后会发生什么):
    #include <stdio.h>
    #include <cuda.h>
    #include <malloc.h>
    #include <stdlib.h>
    
    static void print_allocation_stats(const char* s)
    {
        printf("%s:\n", s);
        printf("--------------------------------------------------\n");
        malloc_stats();
        printf("--------------------------------------------------\n\n");
    }
    
    int main()
    {
        display_mallinfo("Initially");
    
        int status = cuInit(0);
        if (status != 0 ) { return EXIT_FAILURE; }
        print_allocation_stats("After CUDA driver initialization");
    
        int device_id = 0;
        unsigned flags = 0;
        CUcontext context_id;
        status = cuCtxCreate(&context_id, flags, device_id);
        if (status != CUDA_SUCCESS ) { return EXIT_FAILURE; }
        print_allocation_stats("After context creation");
    
        status = cuCtxDestroy(context_id);
        if (status != CUDA_SUCCESS ) { return EXIT_FAILURE; }
        print_allocation_stats("After context destruction");
        return EXIT_SUCCESS;
    }
    
    (请注意,这使用了一个 glibc 特定的函数,而不是在标准库中。)
    总结结果并剪掉不相关的部分:


    程序中的点
    总字节数
    正在使用
    最大 MMAP 区域
    最大 MMAP 字节


    最初
    135168
    1632
    0
    0

    CUDA驱动初始化后
    552960
    439120
    2
    307200

    上下文创建后
    9314304
    6858208
    8
    6643712

    上下文破坏后
    7016448
    580688
    8
    6643712


    所以 CUDA 以 开头0.5 MB 并在分配上下文后占用 9.3 MB (在销毁上下文时返回到 7.0 MB)。 9 MB 仍然是很多内存,因为没有做任何事情;但是 - 也许其中一些是全零,或未初始化,或写时复制,在这种情况下它并没有真正占用那么多内存。
    在 CUDA 8 和 CUDA 10 驱动程序发布之间的两年内,内存使用可能会显着提高,但我对此表示怀疑。所以 - 看起来你的问题是 Windows 特定的。
    另外,我应该提到我没有创建 OpenGL 上下文 - 这是 OP 问题的另一部分;所以我还没有估计需要多少内存。 OP 提出了总和是否大于其部分的问题,即如果还存在 OpenGL 上下文,CUDA 上下文是否会占用更多内存;相信不应该是这样,但欢迎读者尝试举报……

    关于windows - 为什么 OpenGL 和 CUDA 上下文内存贪婪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47462886/

    相关文章:

    随机生成器和 CUDA

    c++ - CUDA 5.5 cudaMemcpyToSymbol、__constant__ 和超出范围错误

    c++ - 可以通过编程方式控制进入笔记本电脑的交流电源吗?

    c++ - 如何在 OpenGL 中进行 2D 缩放(GLFW,很高兴)?

    c++ - 围绕 OpenGL 场景中的对象旋转有困难

    opencv - 使用CUDA使用最近的邻域调整图像大小

    java - Windows 上的反向 dns 查找会阻止无法解析的 IP 地址几秒钟

    c++ - windows和linux差异: backslash and forward slash in c++

    python 3.6.1 需要安装 windows 7 service pack 1

    c - OpenGL4 gl_texture_2d_array不会显示