驱动程序持久性

1. 简介

与 NVIDIA GPU 的任何交互都需要运行内核模式驱动程序的实例。此驱动程序在某些环境中可能是持久的,而在其他环境中可能是瞬态的。本文档介绍了默认的驱动程序行为以及修改该行为的选项。

2. 概述

NVIDIA 内核模式驱动程序必须运行并连接到目标 GPU 设备,然后才能与该设备进行任何用户交互。驱动程序的行为因操作系统而异。通常,如果内核模式驱动程序尚未运行或连接到目标 GPU,则任何尝试与该 GPU 交互的程序的调用都将透明地导致驱动程序加载和/或初始化 GPU。当所有 GPU 客户端终止时,驱动程序将随后反初始化 GPU。驱动程序加载行为对于最终用户在以下两个方面非常重要

  • 应用程序启动延迟

    由于 ECC 清理行为,触发 GPU 初始化的应用程序可能会为每个 GPU 产生较短的(1-3 秒数量级)启动成本。如果 GPU 已经初始化,则不会发生此清理。

  • 驱动程序状态的保留

    如果驱动程序反初始化 GPU,则与该 GPU 关联的某些非持久状态将丢失,并在下次初始化 GPU 时恢复为默认值。请参阅 数据持久性。为避免这种情况,应保持 GPU 初始化。

默认驱动程序行为在不同操作系统之间有所不同

2.1. Windows

在 Windows 上,内核模式驱动程序在 Windows 启动时加载,并保持加载状态直到 Windows 关机。因此,Windows 用户可以主要忽略本文档中描述的驱动程序持久性影响。

注意

驱动程序重新加载事件,例如由于 TDR 或新驱动程序安装,将导致非持久状态的重置。

2.2. Linux

在默认情况下在目标 GPU 上运行 X 的 Linux 系统下,内核模式驱动程序通常会从机器启动到关机进行初始化并保持活动状态,这要归功于 X 进程。在无头系统或没有长期运行的类似 X 的客户端维护目标 GPU 句柄的情况下,每次目标 GPU 应用程序启动和停止时,内核模式驱动程序都会初始化和反初始化目标 GPU。在 HPC 环境中,这种情况非常普遍。由于通常希望在这些情况下保持 GPU 初始化,因此 NVIDIA 提供了两个选项来更改驱动程序行为:持久化模式 (传统)持久化守护程序

3. 数据持久性

不同类别的驱动程序状态具有不同的生命周期持续时间。了解这些差异非常重要,因为这会影响 GPU 管理功能(如时钟设置、ECC 模式等)的行为。通常,驱动程序状态分为以下几类。这并非旨在成为详尽的列表,但将涵盖常见情况

3.1. GPU 初始化生命周期

此类型的状态从驱动程序初始化 GPU 时开始,到 GPU 被反初始化时结束。这是最窄的生命周期,因为内核驱动程序本身仍在加载并且可能正在管理其他 GPU。如果客户端应用程序尝试访问 GPU,则 GPU 通常会初始化 GPU。GPU 通常在最后一个客户端退出后被反初始化。

状态

  • 计算模式、记帐模式、持久化模式

  • 应用程序时钟、应用程序时钟权限设置

  • 基于软件的功耗上限限制

  • 易失性 ECC 错误、待处理的已停用页

3.2. 内核驱动程序生命周期

此类型的状态从驱动程序加载时开始,到驱动程序卸载时结束(例如,rmmod)。在大多数环境中,这是整个机器启动周期。例外情况包括 GPU 重置事件和驱动程序安装。

状态

  • 记帐进程数据

3.3. GPU 板卡生命周期

此类型的状态跨越启动周期,因为它存储在板卡的持久性 inforom 中。在某些情况下,此类状态可以显式清除,但一般来说,此状态被视为在板卡的整个生命周期内都是持久的 - 或者直到用户下次更改为止。

状态

  • ECC 模式、聚合 ECC 错误、已停用页

  • GPU 操作模式、驱动程序模型

4. 背景

NVIDIA GPU 驱动程序历来遵循 Unix 设计理念,仅在用户配置系统执行此操作时才初始化软件和硬件状态。传统上,此配置是通过 X 服务器完成的,并且仅当 X 服务器(代表用户)请求启用 GPU 时才初始化 GPU。这对于在不重启的情况下重新配置 GPU 的能力非常重要(例如,更改 SLI 模式或总线设置,尤其是在 AGP 时代)。

最近,这已被证明在仅计算环境中是一个问题,在这些环境中,不使用 X,并且通过 CUDA 库的瞬态实例化来访问 GPU。这导致 GPU 状态比用户真正希望的更频繁地初始化和反初始化,并导致每个 CUDA 作业的加载时间过长,约为几秒。

NVIDIA 以前提供了持久化模式来解决此问题。这是一种内核级解决方案,可以使用 nvidia-smi 进行配置。这种方法可以防止内核模块在没有用户软件使用 GPU 时完全卸载软件和硬件状态。但是,这种方法与系统的其余部分产生了微妙的交互问题,使得维护变得困难。

NVIDIA 持久化守护程序的目的是用更强大的用户空间解决方案取代这种内核级解决方案。这使仅计算环境能够更紧密地类似于 NVIDIA GPU 驱动程序最初设计的传统图形环境。

5. 持久化模式 (传统)

持久化模式是用户可设置的驱动程序属性的术语,即使没有客户端连接到目标 GPU,该属性也使目标 GPU 保持初始化状态。此解决方案已接近生命周期结束,最终将被弃用,转而使用 持久化守护程序

可以使用 nvidia-smi 或通过 NVML API 以编程方式设置持久化模式。

要使用 nvidia-smi 启用持久化模式(以 root 用户身份)

nvidia-smi -i <target gpu> -pm ENABLED
   Enabled persistence mode for GPU <target gpu>.
   All done.

要使用 nvidia-smi 查看当前持久化模式

nvidia-smi -i <target gpu> - q
    ==============NVSMI LOG==============

    Timestamp                           : ----
    Driver Version                      : ----

    Attached GPUs                       : ----
    GPU 0000:01:00.0
        Product Name                    : ----
        Display Mode                    : ----
        Display Active                  : ----
        Persistence Mode                : Enabled
        Accounting Mode                 : ----
        ...

5.1. 支持的环境

  • 驱动程序:所有发布的驱动程序版本

  • 操作系统:所有标准驱动程序支持的 Linux 平台

  • GPU:所有发布的 Data Center、Quadro 和 GRID 产品

6. 持久化守护程序

NVIDIA 正在 Linux 上提供用户空间守护程序,以支持跨 CUDA 作业运行的驱动程序状态持久性。守护程序方法为此问题提供了比持久化模式更优雅、更强大的解决方案。

在不久的将来,NVIDIA 将支持这两种解决方案,但未来的所有开发和错误修复都将集中在守护程序上。

守护程序安装在 /usr/bin 中,而示例安装和 init 脚本包含在驱动程序文档目录中。这些脚本作为指导,用于安装守护程序以在系统启动时为某些常见的 init 系统运行;由于 init 系统配置的多样性,它们可能需要针对某些发行版进行一些更改。

NVIDIA 鼓励客户在其最早可用时转移到此守护程序方法。

6.1. 支持的环境

  • 驱动程序:R319 及更高版本

  • 操作系统:所有标准驱动程序支持的 Linux 平台

  • GPU:所有发布的 Data Center、Quadro 和 GRID 产品

6.2. 实现细节

在运行 NVIDIA GPU 驱动程序的 Linux 系统上,客户端通过打开其设备文件来连接 GPU。相反,通过关闭设备文件来分离 GPU。只要一个或多个客户端打开设备文件,GPU 状态就会保持加载在驱动程序中。一旦所有客户端都关闭了设备文件,除非启用了持久化模式,否则 GPU 状态将被卸载。

为了模拟图形环境而又不产生用户空间图形驱动程序的开销,我们实现了 NVIDIA 持久化守护程序,它本质上在后台运行并保持设备文件打开状态。守护程序使用 libnvidia-cfg 基于其 PCI 总线地址打开和关闭正确的设备文件,并提供 RPC 接口来单独控制每个 GPU 的持久化模式。因此,当守护程序保持设备文件打开时,至少有一个客户端(即守护程序)连接了 GPU,并且驱动程序不会卸载 GPU 状态。一旦守护程序开始运行,即使所有设备的持久化模式都已禁用,它也会在后台保持运行状态,直到被终止。

由于解决方案的性质,守护程序可以用作我们现在称为“传统持久化模式”的直接替代品,该模式在 NVIDIA 内核模式驱动程序中实现。在驱动程序版本 319 中,NVIDIA SMI 已更新为使用守护程序的 RPC 接口来使用守护程序设置持久化模式(如果守护程序正在运行),如果守护程序未运行,则将回退到在内核模式驱动程序中设置传统持久化模式。所有这些都由 NVIDIA SMI 透明地处理,因此持久化模式的配置方式应该没有任何变化。最终,一旦 NVIDIA 持久化守护程序在相关用例中得到广泛采用,传统持久化模式将被弃用并移除。

6.3. 权限和安全性

NVIDIA 持久化守护程序在 Linux 上提供了更强大的持久化模式实现,因为它只是模拟 GPU 的外部客户端,但实际上并没有将 GPU 用于任何工作。这样,它使 NVIDIA GPU 驱动程序在其原始设计的假设范围内运行。

一旦守护程序运行,启用持久化模式的开销极小。守护程序将只是休眠等待命令。

守护程序不需要超级用户权限即可运行 - 但是,它确实需要超级用户权限才能在 /var/run 中设置一些运行时数据。守护程序允许两种机制以非超级用户权限的用户身份运行

  • 管理员(或以超级用户权限运行的脚本)可以创建 /var/run/nvidia-persistenced 目录,并使用 chown 将其更改为守护程序将要运行的用户。然后可以使用 su 或类似命令以预期用户身份运行守护程序。在这种情况下,当守护程序被终止时,/var/run/nvidia-persistenced 目录将不会被删除。

  • 守护程序可以使用超级用户权限启动,并使用 --user 选项。这将强制守护程序在创建 /var/run/nvidia-persistenced 目录后尽快放弃其超级用户权限,并以指定用户身份运行。请注意,使用此机制,守护程序可能无法在被终止时删除 /var/run/nvidia-persistenced 目录,因为该用户可能没有对 /var/run 的写入权限。

请注意,在这两种情况下,守护程序都可能无法在被终止时删除其运行时数据目录,因此此任务通常应由守护程序的 init 脚本或服务处理。

守护程序也可以通过简单地省略 --user 选项以永久超级用户权限运行,但这不建议这样做,并且对于功能来说也不是必需的。

守护程序还提供了 --verbose 选项,该选项会增加其到 syslog 的日志记录输出,以用于调试目的。

守护程序的源代码也根据 MIT 许可证提供,以允许第二方和第三方安全审核。

6.4. 用法

要运行 NVIDIA 持久化守护程序,只需运行(以 root 用户身份)

# nvidia-persistenced --user foo

在执行少量需要超级用户权限的设置任务后,守护程序将放弃超级用户权限并以用户 'foo' 身份运行。

您可以使用 NVIDIA SMI 更改持久化模式设置。例如,要禁用所有 GPU 上的持久化模式,只需运行(再次以 root 用户身份)

# nvidia-smi -pm 0

请参阅 NVIDIA GPU 驱动程序安装程序安装的 nvidia-persistenced(1) 手册页,或以下命令的输出

% nvidia-persistenced --help

以获取详细的用法信息。

有关安装守护程序以始终在系统启动时运行的详细信息,请参阅下一节。

6.5. 安装注意事项

我们无法立即弃用传统持久化模式并透明地切换到 NVIDIA 持久化守护程序的原因是,目前我们无法保证 NVIDIA 持久化守护程序将运行。这将是一个功能倒退,因为持久化模式可能无法开箱即用。

NVIDIA 持久化守护程序随驱动程序版本 319 开始的 NVIDIA Linux GPU 驱动程序一起发布,并由安装程序安装为 /usr/bin/nvidia-persistenced。理想情况下,守护程序应根据 Linux 发行版的 init 系统在系统初始化时透明地启动,并在系统关机时退出。不幸的是,在 Linux 上安装应用程序以在系统初始化时启动没有单一标准,因此我们无法在 NVIDIA GPU 驱动程序支持的各种系统上可靠地做到这一点。

因此,我们希望鼓励各个发行版(通常重新打包 NVIDIA GPU 驱动程序以通过其软件包管理器进行安装)安装 NVIDIA 持久化守护程序以在系统初始化时启动,一旦 init 系统已知,这是一项几乎微不足道的任务。为此,我们在驱动程序包中提供了示例“init 脚本”,以帮助进行此安装。这些脚本尝试涵盖当今 Linux 发行版中发现的三种最流行的 init 系统:SystemV、systemd 和 Upstart。示例脚本还附带一个安装程序脚本,该脚本尝试检测 init 系统并为用户安装适当的脚本。示例脚本和安装程序脚本由 NVIDIA GPU 驱动程序安装程序安装到 /usr/share/doc/NVIDIA_GLX-1.0/sample/nvidia-persistenced-init.tar.bz2。它们不会被驱动程序安装程序解压缩或运行,因为我们无法保证它们在所有受支持的系统上都能开箱即用。

默认情况下,安装程序脚本尝试为守护程序要运行的用户创建一个新的系统用户,并且示例 init 脚本演示了 权限和安全性 中描述的第二个选项,用于在没有超级用户权限的情况下运行守护程序。

6.6. 客户可见性

守护程序对最终客户可见,因为它通常需要手动安装到 init 系统中。但是,在执行初始安装步骤后,守护程序应在后台透明地运行,NVIDIA SMI 处理必要的切换以确定是否可以使用守护程序持久化模式。理想情况下,传统持久化模式的最终弃用和移除对于使用守护程序的客户来说将是透明的。

7. 通知

本文档仅供参考,不应被视为对产品的特定功能、状况或质量的保证。NVIDIA Corporation(“NVIDIA”)对本文档中包含的信息的准确性或完整性不作任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。NVIDIA 对因使用此类信息或因使用此类信息而可能导致的侵犯第三方专利或其他权利的行为不承担任何责任。本文档并非承诺开发、发布或交付任何材料(如下定义)、代码或功能。

NVIDIA 保留随时对此文档进行更正、修改、增强、改进和任何其他更改的权利,恕不另行通知。

客户在下订单前应获取最新的相关信息,并应验证此类信息是否为最新且完整。

NVIDIA 产品根据订单确认时提供的 NVIDIA 标准销售条款和条件进行销售,除非 NVIDIA 和客户的授权代表签署的个别销售协议(“销售条款”)另有约定。NVIDIA 在此明确反对将任何客户通用条款和条件应用于购买本文档中引用的 NVIDIA 产品。本文档未直接或间接形成任何合同义务。

NVIDIA 产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命支持设备,也不适用于 NVIDIA 产品的故障或 malfunction 可以合理预期会导致人身伤害、死亡或财产或环境损害的应用。NVIDIA 对在上述设备或应用中包含和/或使用 NVIDIA 产品不承担任何责任,因此,此类包含和/或使用由客户自行承担风险。

NVIDIA 不保证基于本文档的产品将适用于任何特定用途。NVIDIA 不一定执行每个产品的所有参数的测试。客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适合并满足客户计划的应用,并执行应用所需的测试,以避免应用或产品的默认设置。客户产品设计中的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档中包含的附加或不同条件和/或要求。NVIDIA 对可能基于或归因于以下原因的任何默认设置、损坏、成本或问题不承担任何责任:(i) 以任何与本文档相悖的方式使用 NVIDIA 产品,或 (ii) 客户产品设计。

本文档未授予任何 NVIDIA 专利权、版权或其他 NVIDIA 知识产权下的任何明示或暗示的许可。NVIDIA 发布的有关第三方产品或服务的信息不构成 NVIDIA 授予使用此类产品或服务的许可,也不构成对其的保证或认可。使用此类信息可能需要获得第三方在其专利或其他知识产权下的许可,或获得 NVIDIA 在 NVIDIA 的专利或其他知识产权下的许可。

只有在事先获得 NVIDIA 书面批准的情况下,才允许复制本文档中的信息,复制时不得进行更改,并且必须完全遵守所有适用的出口法律和法规,并附带所有相关的条件、限制和通知。

本文档和所有 NVIDIA 设计规范、参考板、文件、图纸、诊断程序、列表和其他文档(统称为“材料”)均按“原样”提供。NVIDIA 对材料不作任何明示、暗示、法定或其他形式的保证,并明确声明不承担所有关于不侵权、适销性和特定用途适用性的暗示保证。在法律未禁止的范围内,在任何情况下,NVIDIA 均不对任何损害负责,包括但不限于任何直接、间接、特殊、偶然、惩罚性或后果性损害,无论其因何种原因引起,也无论其责任理论如何,即使 NVIDIA 已被告知发生此类损害的可能性。尽管客户可能因任何原因遭受任何损害,但 NVIDIA 对本文所述产品的客户的累计责任应根据产品的销售条款进行限制。

7.1. 商标

NVIDIA 和 NVIDIA 徽标是 NVIDIA Corporation 在美国和其他国家/地区的商标或注册商标。其他公司和产品名称可能是与其关联的各自公司的商标。