【问题标题】:How'd multi-GPU programming work with Vulkan?多 GPU 编程如何与 Vulkan 一起工作?
【发布时间】:2015-10-28 07:17:45
【问题描述】:

在 Vulkan 中使用多 GPU 是否类似于创建多个命令队列然后在它们之间划分命令缓冲区?

有2个问题:

  1. 在 OpenGL 中,我们使用 GLEW 来获取函数。对于超过 1 个 GPU,每个 GPU 都有自己的驱动程序。我们是如何使用 Vulkan 的?
  2. 是否部分帧由 GPU 生成,而其他部分由其他 GPU 生成,例如使用 Intel GPU 渲染 UI 和 AMD 或 Nvidia GPU 在 labtops 中渲染游戏屏幕?还是会在 GPU 中生成一帧,然后在另一个 GPU 中生成下一帧?

【问题讨论】:

    标签: gpu multi-gpu vulkan


    【解决方案1】:

    更新了最新信息,现在 Vulkan 已经存在。

    有两种多 GPU 设置:多 GPU 是某些 SLI 风格设置的一部分,另一种不是。 Vulkan 两者都支持,并且在同一台计算机上同时支持它们。也就是说,您可以拥有两个一起 SLI 的 NVIDIA GPU,以及英特尔嵌入式 GPU,而 Vulkan 可以与它​​们全部交互。

    非 SLI 设置

    在 Vulkan 中,有一个叫做 Vulkan 实例的东西。这代表了基本的 Vulkan 系统本身;各个设备将自己注册到实例。 Vulkan 实例系统本质上是由 Vulkan SDK 实现的。

    物理设备表示实现与 GPU 的接口的特定硬件。公开 Vulkan 实现的每个硬件都是通过将其物理设备注册到实例系统来实现的。您可以查询哪些物理设备可用,以及它们的一些基本属性(它们的名称、它们提供的内存量等)。

    然后为您使用的物理设备创建逻辑设备。逻辑设备是您在 Vulkan 中实际操作的方式。它们有队列、命令缓冲区等。每个逻辑设备都是独立的……主要是。

    现在,您可以绕过整个“实例”并手动加载设备。但你真的不应该。至少,除非您处于开发的最后阶段,否则不会。 Vulkan 层对于日常调试来说太重要了,不能选择退出。

    Vulkan 1.1 中的核心机制允许单个设备能够将某些信息传递给其他设备。在 1.1 中,只有特定种类的信息可以在 物理 设备之间共享(即,栅栏和信号量,即便如此,也只能在 Linux 上通过同步文件)。虽然这些 API 可以提供在两个物理设备之间共享数据的机制,但目前,大多数数据共享形式的限制是两个物理设备必须具有匹配的 UUID(因此是相同的物理设备)。

    SLI 设置

    两个 Vulkan 1.0 扩展包括处理 SLI:KHR_device_groupKHR_device_group_creation。前者用于处理 Vulkan 中的“设备组”,而后者是用于创建设备分组设备的实例扩展。这两个都是 Vulkan 1.1 的核心。

    这样做的想法是,SLI 聚合被公开为单个 VkDevice,它是由多个 VkPhysicalDevices 创建的。每个内部物理设备都是一个“子设备”。您可以查询子设备及其相关属性。内存分配特定于特定的子设备。资源对象(缓冲区和图像)并非特定于子设备,但它们可以与不同子设备上的不同内存分配相关联。

    命令缓冲区和队列并不特定于子设备;当您在队列上执行 CB 时,驱动程序会确定它将在哪个子设备上运行,并使用适当的 GPU 指针填充使用图像/缓冲区的描述符,以用于这些图像/缓冲区具有的内存被绑定到那些特定的子设备上。

    交替帧渲染只是在一帧上呈现从一个子设备生成的图像,然后在另一帧上呈现来自不同子设备的图像。拆分帧渲染由更复杂的机制处理,您可以在其中定义要在设备之间拆分的渲染命令的目标图像的内存。你甚至可以用漂亮的图片来做到这一点。

    【讨论】:

    • +1 – 请问你去过哪里?你被错过了。话虽如此,我希望你不介意我在我的服务器上镜像了你的 OpenGL 教程,因为你的域前一段时间倒闭了。
    • 我应该在发布后问的,但你似乎有一些信息。确认后我会选择它。
    • @NicolBolas Vulkan 1.1 中的核心机制允许单个设备能够将某些信息传达给其他设备。 - 哪些机制/扩展允许这样做?据我所知,例如共享同步原语或内存(通过从外部资源导出/导入)只能在从同一物理设备创建的逻辑设备上完成。
    • @Ekzuzy:已更新。
    【解决方案2】:
    1. 在 vulkan 中,您需要枚举设备并选择要使用的设备。没有什么可以阻止您尝试分别使用 2 个不同的。每个 vulkan 调用至少需要 1 个参数作为上下文。然后加载器层将调用转发给正确的驱动程序。或者你可以分别为每个设备加载函数,避免加载器的蹦床。

    2. 需要将生成的帧转发到连接到屏幕的卡上进行显示。因此,更有可能 1 个 GPU 负责图形,​​而其他 GPU 则用于物理。

      一次只能将一个设备连接到特定表面,因此设备需要获取渲染帧以将其复制到推送到屏幕的可渲染图像中。

    【讨论】:

    • 您在 (1) 中使用的事实陈述和术语是否都包含在 Khronos 和 Khronos 成员公司公开发布的文件中的披露中?请注意,我并不是说它们不是。我很高兴能够标出不断扩大的公共信息前沿。 SIGGRAPH 可能会看到向外迈出一步。
    • @ahcox 第 1 点在今年早些时候的演讲中被明确提及。第 2 点(就像与显示器的所有接口一样)是推测。
    • ahcox 这也是 Mantle 的工作方式,尽管无论如何都不是 Vulkan 规范,但它是 Vulkan(和 DX12)使用的基本形式。
    • 我找到了 wccftech.com/… 关于 Directx 12。
    【解决方案3】:

    设备组是要走的路。查看 vulkan 规范以获取文档。 Vulkan 处理所有对其他 GPU 的调度(当它们通过 sli/crossfire 连接时)。您需要做的就是告诉 vulkan 调度是如何完成的(例如,在 GPU 上调度一帧,在另一帧上调度下一帧)。如果您需要进行计算工作,则需要单独处理每个 GPU。请找到参考链接:https://www.ea.com/seed/news/khronos-munich-2018-halcyon-vulkan

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      相关资源
      最近更新 更多