为什么OpenGL和CUDA上下文是内存贪婪的?

时间:2017-11-23 20:29:39

标签: windows opengl cuda operating-system

我开发的软件通常包括OpenGL和Nvidia CUDA SDK。最近我也开始寻求优化运行时内存占用的方法。我注意到以下内容(调试和发布版本仅相差4-7 Mb):< / p>

应用程序启动 - 小于 1 Mb 总计

OpenGL 4.5上下文创建(+ GLEW加载器初始化) - 45 Mb 总计

CUDA 8.0上下文(Driver API)创建 114 Mb 总计。

如果我在&#34;无头&#34;中创建OpenGL上下文模式,GL上下文使用3 Mb,这可能是默认帧缓冲区分配。这是有道理的,因为窗口大小是640x360。

因此,在OpenGL和CUDA上下文完成后,该过程已消耗 114 Mb

现在,我对GL和CUDA上下文创建过程中发生的操作系统特定内容缺乏深入了解,但GL的45 Mb和CUDA的68 Mb对我来说似乎很多。我知道通常有几兆字节用于系统帧缓冲区,函数指针(可能大部分分配发生在驱动程序端)。但是只用&#34;空的&#34;达到100 Mb以上上下文看起来太多了。

我想知道:

  1. 为什么GL / CUDA上下文创建消耗了如此大量的内存?

  2. 有优化方法吗?

  3. 正在测试的系统设置: Windows 10 64位。 NVIDIA GTX 960 GPU(驱动程序版本:388.31)。 8 Gb RAM。 Visual Studio 2015,64位C ++控制台项目。

    我使用Visual Studio内置诊断工具测量内存消耗 - &gt;进程记忆部分。

    更新

    我按照datenwolf的建议尝试了Process Explorer。这是我得到的截图,(我的底部标有黄色的过程):

    enter image description here

    我很感激对这些信息的一些解释。我一直在关注私人字节&#34;在&#34; VS诊断工具&#34;窗口。但在这里我也看到&#34;工作集&#34;,&#34; WS Private&#34;哪一个正确显示了我的进程当前使用了多少内存? 281,320K看起来太多了,因为正如我上面所说,启动过程什么也没做,但创建了CUDA和OpenGL上下文。

1 个答案:

答案 0 :(得分:1)

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


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

  • CUDA 版本:10.2.89
  • 操作系统发行版:Devuan GNU/Linux Beowulf(~= 没有 systemd 的 Debian Buster)
  • 内核:Linux 5.2.0
  • 处理器:Intel 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 上下文是否会占用更多内存;我认为不应该是这样,但欢迎读者尝试和报告...