我可以在 OpenGL 中使用不同的多 GPU 吗?

Posted

技术标签:

【中文标题】我可以在 OpenGL 中使用不同的多 GPU 吗?【英文标题】:Can I use different multiGPU in OpenGL? 【发布时间】:2020-10-03 21:49:16 【问题描述】:

我读到了OpenGL multi-GPU support。我目前正在使用支持 OpenGL 4.5 的 NVIDIA 卡。我的 iGPU 是 Intel HD 610,我不知道它是 openGL 版本。现在我尝试将两者一起使用。我知道 DirectX 12 可以支持不同的 GPU。 OpenGL 是否同时支持 Intel iGPU 和 NVIDIA GPU?我可以将 iGPU 端口用于我的显示器并在搅拌机中使用 NVIDIA 卡进行循环渲染吗? (最后一点很重要,因为我的显示器只支持 VGA。)

【问题讨论】:

【参考方案1】:

如果您的机器上有来自不同供应商的 GPU,则很容易选择哪一个与 OpenGL 一起使用。 为此,请在创建 OpenGL 上下文之前调用以下函数:

// pass one of these to choose_ogl_vendor()
#define VENDOR_AMD "PCI\\VEN_1002&"
#define VENDOR_NVIDIA "PCI\\VEN_10DE&"
#define VENDOR_INTEL "PCI\\VEN_8086&"
void choose_ogl_vendor(const char *vendor_id)

    int idx;
    DISPLAY_DEVICEA dd;
    HDC dc;
    PIXELFORMATDESCRIPTOR pfd;

    dd.cb = sizeof(dd);
    idx = 0;
    while (1) 
        if (!EnumDisplayDevicesA(NULL, idx, &dd, 0))
            return; // not found!
        if (strstr(dd.DeviceID, vendor_id))
            break; // there we go
        idx += 1;
    

    dc = CreateDCA(dd.DeviceName, NULL, NULL, NULL);
    memset(&pfd, 0, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    // those flags are not important, they just need to be valid (and nondemanding, just in case).
    // later you will use whatever flags you wish when you are creating your actual gl context
    pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER|PFD_DEPTH_DONTCARE;
    ChoosePixelFormat(dc, &pfd);
    DeleteDC(dc);

此函数将强制 opengl32.dll 加载您选择的 ogl 驱动程序。 之后,继续进行通常的 OpenGL 上下文创建和初始化工作。

但是请注意,一旦加载了 GPU 供应商的驱动程序,就无法在进程的整个生命周期内更改它。

【讨论】:

【参考方案2】:

OpenGL 是很久以前设计的,因此采用此 API 来处理多个 GPU 设备是有问题的。与 OpenCL 或 Vulkan 不同,它们从一开始就具有选择系统中可用设备/驱动程序的一些基本含义,OpenGL(或特别是 - WGL、GLX、EGL 接口将 OpenGL 绑定到窗口系统)没有任何 - 操作系统完全负责使用不明确的逻辑选择驱动程序。

OpenGL 实际提供了什么:

GPU 亲和性/在同一 OpenGL 驱动程序中的选择(WGL_AMD_gpu_association 和 WGL_NV_gpu_affinity)。这允许管理同一供应商 GeForce+GeForce 或 Radeon+Radeon(在后一种情况下包括 iGPU)的 GPU 串联,但不能管理不同供应商的 GPU。 Linux 上的 MESA 驱动也支持GLX_MESA_query_renderer 扩展,但目前它只允许列出系统中所有可用的渲染器,而不是选择特定的。 首选 GPU 在 iGPU+Discrete 串联中。特定的 Intel+GeForce 串联提供驱动程序设置(通常在 NVIDIA 控制面板中),允许特定应用程序使用 iGPU 或 GeForce。应用程序也可能使用技巧(例如在 DLL 中导出符号)要求驱动程序更喜欢离散 GPU 而不是 iGPU。无法在同一个应用程序中同时使用两个 GPU。另请注意,这仅适用于配备特殊 Intel+NVIDIA 驱动程序的笔记本电脑,不适用于普通台式机配置。 活动 GPU 在其他多 GPU(桌面)配置中。操作系统完全负责使用不明确的逻辑选择驱动程序。在交互式会话中,Windows 根据物理连接到哪个 GPU 主显示器来决定加载哪个 OpenGL 驱动程序(以前,在某处说过,窗口位置改变了这个逻辑,但现代 Windows 系统似乎不再如此)。在 RDP 会话中,逻辑不明确且不可配置 - 它以某种方式由 PCI-E 插槽中的 GPU 顺序确定;选择某些 GPU 的唯一方法是在设备管理器中禁用所有其他 GPU。

无论如何,即使在支持这一点的 API 中使用多个 GPU,也是相当复杂的事情,需要应用程序开发人员付出很多努力:管理多个设备、重复的内存管理、分割渲染视口、平衡和同步。即使在最好的情况下,对于 2 个相同的 GPU,收益也将远低于 2 倍,因为必须在两个 GPU 上处理部分渲染管道(例如在this video 关于 VR 渲染器的阴影渲染 - 所以 2 个 GPU 只提供30-35% 的性能提升)。

同时,由于额外的平衡问题以及不一致的 GPU(驱动程序)功能,在多 GPU 配置中使用不相等的 GPU 更加令人头疼。在 Intel iGPU + Discrete GPU 串联中,第一个不仅速度较慢,而且在 OpenGL 核心版本或扩展方面具有较低的能力。不过,AMD 展示了一些多 GPU iGPU+离散 GPU 设置,并带来了一些性能提升。

【讨论】:

以上是关于我可以在 OpenGL 中使用不同的多 GPU 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OpenGL 监控 Java 中的 GPU 使用情况?

您可以制作自己的渲染管道吗?

OpenGL 3.3 两个 GPU 上的两个不同结果 nVidia Optimus 与阴影映射

在 openGL 中,模型坐标应该在我的 CPU 上还是通过 OpenGL 调用在 GPU 上计算?

在 MacOS 上使用 OpenGL 的 GPU 时序

我可以使用qt中的OpenGL功能而不需要任何类型的小部件吗?