理解 NVIDIA GPU 性能: Utilization vs. Saturation

翻译自 Understanding NVIDIA GPU Performance: Utilization vs. Saturation (2023)

GPU 性能指标工具如 nvidia-smi,我们一般拿这个工具查看显卡使用率是否打满。

(develop) (base) oldpan@oldpan-OptiPlex-7000:~/code$ nvidia-smi
Sun Apr 21 13:53:28 2024       
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.113.01             Driver Version: 535.113.01   CUDA Version: 12.2     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA RTX A4000               Off | 00000000:01:00.0 Off |                  Off |
| 41%   32C    P8               9W / 140W |   2361MiB / 16376MiB |      0%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+
                                                                                         
+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|    0   N/A  N/A      1564      G   /usr/lib/xorg/Xorg                          110MiB |
|    0   N/A  N/A      3122      G   /usr/lib/xorg/Xorg                          655MiB |
|    0   N/A  N/A      3273      G   /usr/bin/gnome-shell                         32MiB |
|    0   N/A  N/A      4020      G   ...bian-installation/ubuntu12_32/steam       76MiB |
|    0   N/A  N/A      4214      G   ./steamwebhelper                            562MiB |
|    0   N/A  N/A      4244      G   ...ures=BackForwardCache,DcheckIsFatal       17MiB |
|    0   N/A  N/A      4415    C+G   /usr/bin/sunshine                           576MiB |
+---------------------------------------------------------------------------------------+

不过要注意这个指标GPU-Util可能和我们想象中的不一样,本博客深入探讨了这一问题,以提供更深入的理解。

1 NVIDIA "GPU util":一个令人困惑的现象

即使只有一个任务在 GPU 的一小部分上运行,由工具如 nvidia-smi 或其他基于 nvml 的工具报告的 "GPU util" 指标可能表明设备完全被占用,这对用户来说相当困惑。

为了提供更清晰的理解,先看一个来自 NVIDIA 开发者论坛 的示例:

__global__ void simple_kernel() {
    while (true) {}
}

int main() {
    simple_kernel<<<1, 1>>>();
    cudaDeviceSynchronize();
}

此代码片段将在一个流多处理器(SM)上启动指定的内核(线程)。正常来算的话,GPU 的“利用率”应该计算为 1 / num_sm * 100%。例如:

  • 如果 GPU 上有 10 个 SM,那么“GPU 利用率”应该是 10%。
  • 如果有 20 个 SM,那么“GPU 利用率”应该是 5%。

但是观察到 nvidia-smi 可能报告 "GPU-Util" 为 100%,如下例输出所示:

$ nvidia-smi
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  Off  | 00000000:1A:00.0 Off |                    0 |
| N/A   42C    P0    67W / 300W |   2602MiB / 32510MiB |    100%      Default |
|                               |                      |                  N/A |
+-------------------------------

+----------------------+----------------------+

问题是什么?让我们找到答案。

2 GPU Util:一个误导性的术语?

先从网上查查资料看看。

2.1 官方文档中的定义

nvidia-smi 命令行工具基于 NVIDIA 管理库 (NVML),遗憾的是它没有开源。为了弄清楚,我们参考了官方 NVML 文档。根据文档,

GPU utilization: Current utilization rates are reported for both the compute resources of the GPU and the memory interface. 报告 GPU 的计算资源和内存接口的当前利用率。

依然不是很清楚,继续查资料。

2.2 探索代码

虽然 NVML 库本身没有开源,但我们发现了可用的开源语言绑定(open-source language bindings)。这意味着我们至少可以访问 structure and field definitions,通常提供在 C/C++ 头文件中。在这里我们选择了 gonvml 项目,它为 NVML 提供了一个 Golang 绑定。这是 NVML 头文件中定义 "GPU Util" 和 “Memory Util”的一个摘录:

// https://github.com/NVIDIA/go-nvml/blob/v0.12.0-1/gen/nvml/nvml.h#L210

/**
 * Utilization information for a device.
 * Each sample period may be between 1 second and 1/6 second, depending on the product being queried.
 */
typedef struct nvmlUtilization_st {
    unsigned int gpu;                //!< 在过去的样本周期内,一个或多个内核在 GPU 上执行的时间百分比
    unsigned int memory;             //!< 在过去的样本周期内,全局(设备)内存被读取或写入的时间百分比
} nvmlUtilization_t;

有了上述注释,我们得到了答案。

2.3 解释

根据 NVML 提供的定义,“利用率”指的是 过去样本期间内某些活动发生的时间百分比。具体来说:

  • GPU 利用率:这代表了一个或多个内核在 GPU 上执行的时间百分比。
  • 内存利用率:这代表了全局(设备)内存在被读取或写入的时间百分比。

换句话说,NVML 定义的“利用率”可能 与我们常规理解不一致。它仅度量设备在给定采样周期内的使用部分时间,而不考虑该时间内使用的流多处理器(SM)数量。通常,我们认为“utilization”是指使用 GPU 处理器的部分。

我不确定为什么 NVIDIA 以这种非传统方式定义“ utilization”。但这可能与“USE”(Utilization/Saturation/Error)方法论中的“ utilization”定义有关。

2.4 “USE” 方法论

如果你熟悉《Systems Performance: Enterprise and the Cloud》这本书,你可能记得 Brendan Gregg 引入的 “USE” 方法论。这种方法论关注三个关键指标:Utilization (利用率), Saturation (饱和度), 和 Errors (错误)。根据“USE”博客,术语定义如下:

  • utilization: 资源忙碌服务工作的平均时间
  • saturation: 资源有额外工作不能服务,经常排队
  • errors: 错误事件计数

“USE”方法论为“利用率”提供了额外的解释:

还有另一个定义,在那里利用率描述 资源被使用的比例,因此 100% 利用率意味着不能接受更多工作,与上述“忙碌”定义不同**。

总之,“USE” 方法论中,“利用率”指的是 资源积极服务或工作的时间部分,而不考虑分配的容量。对于后者,使用术语“饱和度”。虽然“USE”方法论为资源使用评估提供了有价值的见解,但重新定义像“利用率”这样的公认术语可能会导致混淆。许多人仍然更喜欢将“利用率”视为容量使用或饱和度的概念。

如果必要的话,替代“利用率”的术语可以是 "used-frequency",表示 设备被利用的频率

2.5 两种度量来源:NVML / DCGM

在大多数情况下,我们主要关心的 metrics 与“ saturation”相关。那么,我们可以在哪里找到这些 GPU 性能指标?

有两种流行的方法来收集 GPU 性能指标:

  1. 使用命令行工具如 nvidia-smi,它可以输出格式如 pretty-print 和 xml 的数据。
  • 此工具内部基于 NVML (NVIDIA 管理库)。
  • 它收集高级指标(high-level metrics),如 GPU 和内存“利用率-utilization”(used-frequency),设备温度,功耗等。
  1. 使用服务如 dcgm-exporter,它可以输出 Prometheus 格式的数据。
  • 此服务内部基于 DCGM (数据中心 GPU 管理)。
  • 除了high-level metrics外,它还可以进行分析并收集有关 GPU 设备的详细 饱和度数据

以下是两组从 nvidia-smidcgm-exporter 收集的仪表板显示的指标:

nvidia-smi 的指标|100%x100%

注意 GPU 利用率为 100%。以下是从 dcgm-exporter 收集的指标:

dcgm-exporter 的指标|100%x100%

我们可以看到 SM 占用率非常低 (<20%),浮点运算 (FP32/FP16/TensorCore) 也保持在非常低的百分比,表明 GPU 用的核不多。

3 结论与建议

3.1 “Utilization” vs. saturation

不确定 NVML 设计者是否故意采用上述提到的“USE”方法论,但其定义的“利用率”(包括 GPU 和内存利用率) 似乎与“USE”标准一致。报道的“利用率-Utilization”仅指示设备使用的频率(以时间百分比),而不考虑利用的具体容量。

3.2 建议:优先考虑饱和度(saturation)指标

虽然 nvidia-smi 是一种常用且方便的工具,但它不是性能测量的最佳选择。对于实际部署中的 GPU 应用,建议使用基于 DCGM 的指标,如 dcgm-exporter 提供的那些。

此外,关注饱和度指标可能会有益。这些指标包括 FP64/FP32/FP16 激活,张量核心激活百分比,NVLINK 带宽,GPU 内存带宽百分比等。

dcgm-exporter 的指标|100%x100%