GPU特点
www.cs.utexas.edu/~pingali/CS…
服务特点
计算过程涉及cpu、内存、gpu、显存多个硬件之间的配合
-
CPU:擅长流程控制和逻辑处理,不规则数据结构,不可预测存储结构,单线程程序,分支密集型算法。
-
GPU:擅长数据并行计算,规则数据结构,可预测存储模式。
-
内存:给CPU提供计算过程中的存储能力
-
显存:给GPU提供计算过程中的存储能力
要想充分利用GPU,本质上就是需要协调这些硬件之间的计算关系。
最理想的配合方式就是CPU只做控制(分支密集型),GPU只做计算(数据密集型),且内存/显存的带宽不存在瓶颈。因为GPU计算速度非常高,在CPU资源有限的情况下,CPU只做控制才可以尽可能地匹配GPU的速率。
服务处理流程
上图是服务端推理服务的整体链路,分析性能瓶颈时应该从整体出发。
以下可能造成GPU利用率瓶颈的一些情况:
软件层次
- RPC/HTTP框架Workers线程配置过少,无法接受足够的请求。CPU和GPU没有足够的任务,处于饥饿状态。 表现是CPU和GPU利用率都不高,但是QPS已达到瓶颈。
- CPU的处理流程中进行了同步IO的一些操作(比如从磁盘或网络读取图片等)。这里由于CPU在等待IO操作就绪而成为瓶颈,而GPU等待CPU控制逻辑从而利用率低。表现是CPU和GPU利用率都不高,但是QPS已达到瓶颈。
- CPU利用率高,但真正处理有效计算的时长占比不高(比如自旋锁、线程数过多造成的上下文切换频繁等)。这里CPU由于无效计算成为瓶颈,GPU等待CPU控制逻辑而利用率低。表现是CPU利用率高而GPU利用率低。
- CPU利用率高,真正处理有效计算的时长占比也高,这里CPU由于性能限制成为瓶颈,GPU等待CPU而利用率低。表现是CPU利用率高而GPU利用率低。
- GPU利用具有明显的时间相关性,某些时间片GPU处于闲置状态。
- 数据传输存在瓶颈,数据传输与计算过程是串行的,GPU有部分时间是在等待数据传输;
- CUDA层面多个kernel函数并行度不高,没有重叠数据传输、CPU和GPU异构设备的计算(cuda multi-stream) 。
硬件层次
-
GPU上第一次执行的计算会比较慢(需要预热)。
-
一批任务同时送到GPU计算,会涉及较少的CPU-GPU同步操作、GPU内部也对这种批处理有所优化。
-
一定程度上,提升GPU的吞吐量而非QPS有利于提高GPU利用率。
-
CPU到GPU之间的通信可能成为瓶颈,要尽量减少通信次数和同步操作,尽量使用异步方式。
优化思路/手段
优化的基本思路是将这些异构硬件作为一个系统看待,并且从一个请求的整体链路来分析可能存在的瓶颈(木桶效应),然后有针对性的去优化,以下是一些常见的手段。
- 根据实际情况对Workers线程数进行调优。
- CPU编程中尽量使用异步方式处理IO逻辑或非计算密集型逻辑。
- 对CPU线程数、加锁等逻辑进行调优,使CPU做有效的工作。
- 如果CPU计算是瓶颈,可以尝试将一些计算迁移到GPU上,尽量使用GPU做计算,CPU只用来做控制。
- 对GPU进行warm up。
- 批处理。
- 编码时有并行计算的编程思想。
- 对于具有时间相关性的GPU服务进行混合部署。
- GPU全链路+显存规划+CUDA multi-stream
- 多个推理进程+MPS / 多个推理线程(针对SM利用率低+SM空间利用率低的情况)
- 对复杂流程的服务进行拆分,让GPU的处理更加纯粹