GPU CUDA编程概念 优化加速 基于GPU的大数据处理和机器学习加速NLP领域的GPU加速案例,Faster Transformer NVIDIA GPU通用推理加速及部署SDK NVIDIA

GPU 相关知识

CPU vs GPU

CPU(Central Processing Unit,中央处理器)和GPU(Graphics Processing Unit,图形处理器)在计算机系统中有各自独特的功能和优势,它们之间的主要区别体现在以下几个方面:

任务分工:

CPU:主要用于处理复杂的计算任务,如运行操作系统、执行应用程序等。它是计算机系统的核心,负责执行各种计算和控制任务。

GPU:专注于图形渲染和大规模并行计算任务。它能够同时处理大量的数据和任务,特别适用于深度学习、科学计算和图形渲染等需要高度并行化的工作负载。

并行处理能力:

CPU:通常包含少量的核心(如四核、八核等),每个核心可以独立执行计算任务,但其并行处理能力相对有限。

GPU:由数以千计的更小的处理器(流处理器)组成,这些处理器可以并行处理数据,使得GPU在处理图像和视频数据时比CPU更加高效。此外,GPU还具有大规模数据并行性,能够加速数据密集型任务。

能效比:

GPU:相比于CPU在相同计算能力下具有更高的能效比,即能够在更低的功耗下完成更多的计算任务。这使得GPU在能源利用和环境保护方面具有更好的表现。

价格:

GPU:价格通常比CPU便宜,但在需要图形处理能力的场合,使用GPU可以节省成本。

编程模型:

CPU:使用通用的编程模型,如C、C++、Java等。

GPU:具有专用的编程模型和框架,如CUDA、OpenCL等,用于支持大规模并行计算和图形渲染。这些编程模型使开发人员能够在GPU上执行各种应用程序,包括科学计算、深度学习、密码学等。

CPU和GPU在计算机系统中各自扮演着不同的角色。CPU是计算机系统的核心,负责执行各种计算和控制任务;而GPU则专注于图形渲染和大规模并行计算任务,为计算机系统提供强大的图形处理能力和计算性能。在实际应用中,CPU和GPU通常会协同工作,以充分发挥各自的优势。

  • CPU: latency-optimized low latency processor

Latency-optimized low latency processor(低延迟优化的处理器):CPU的主要设计目标是减少延迟,即减少从发出指令到得到结果所需的时间。为了实现这一目标,CPU通常具有复杂的缓存层次结构、分支预测和指令流水线等技术,以最大化单个任务的执行效率。

前端消耗大:这里的“前端消耗大”通常指的是CPU在处理任务时需要经过复杂的指令解码、调度和执行流程。这些流程对于单个复杂任务的执行非常有效,但对于大规模并行任务来说,可能会成为性能瓶颈。

  • GPU: throughput-optimized high throughput processor

Throughput-optimized high throughput processor(吞吐量优化的高吞吐量处理器):GPU的设计目标是最大化吞吐量,即单位时间内可以处理的任务数量。为了实现这一目标,GPU采用了大量的简单处理单元(流处理器)来并行处理数据。这种设计使得GPU在处理大规模并行任务(如图像处理、视频编码解码、科学计算等)时具有非常高的效率。

并行计算能力:GPU的并行计算能力是其最大的优势之一。由于其拥有大量的处理单元和高速的内存带宽,GPU可以轻松地处理大量的数据,并且在并行计算任务中展现出比CPU更高的效率。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

共享卡 —— 如何实现算力和显存隔离
  • 隔离方式:时间片 vs 空间
    时间片隔离:通过分配不同的时间段给不同的任务或进程,实现GPU资源的分时复用。这种方式适用于需要并行处理多个任务但每个任务对GPU资源需求不高的场景。
    空间隔离:也称为硬隔离或物理隔离,是通过将GPU资源划分为不同的区域或区域组,并将它们分配给不同的任务或进程。这种方式提供了更高的隔离级别,但可能会降低资源的使用效率。

  • 隔离级别:不隔离 vs 强隔离 vs 弹性
    不隔离:所有任务或进程共享GPU资源,没有明确的隔离边界。这种方式资源使用效率高,但可能导致资源竞争和冲突。
    强隔离:通过硬件或软件的方式,将GPU资源划分为独立的区域或区域组,并为每个任务或进程分配独立的资源。这种方式提供了最高的隔离级别,但可能会降低资源的使用效率。
    弹性隔离:根据任务或进程的需求动态调整隔离级别。当任务或进程对GPU资源的需求较高时,可以提供更高的隔离级别;当需求较低时,则降低隔离级别以提高资源使用效率。

  • 几种隔离技术对比:

    • vGPU(Grid)(Nvidia):虚拟化;容器化支持不好,license,基于虚拟化的GPU隔离技术。它允许将物理GPU划分为多个虚拟GPU(vGPU),并为每个虚拟机或容器分配一个或多个vGPU。然而,这种技术对容器化的支持不够好,并且可能需要购买额外的许可证。
    • vCuda(腾讯):cuda hook;性能损耗严重,通过hook CUDA API的方式实现GPU隔离。这种方法可能会引入较大的性能损耗,因为它需要在每次CUDA调用时进行额外的检查和处理。
    • cGPU(Alibaba):ioctl;损耗小,硬隔离,侵入内核(机器容易坏),基于ioctl接口实现GPU隔离。这种方法损耗较小,并且可以实现硬隔离。然而,由于它侵入内核,可能会对系统的稳定性和安全性产生一定的影响。
    • MPS(Nvidia):thread;显存隔离,故障隔离不好,进程级别,进程数量会受限于显存,基于线程的GPU隔离技术。它允许在单个GPU上同时运行多个进程,并通过限制每个进程使用的显存量来实现显存隔离。然而,由于进程级别的隔离,进程数量可能会受限于显存大小。
    • MIG(~A100):sm/global memory;硬件层面隔离,一种基于硬件的GPU隔离技术。它允许将单个GPU划分为多个独立的GPU实例(MIG实例),并为每个实例分配独立的显存和SM(流处理器)。这种技术提供了较高的隔离级别和故障隔离能力,但可能需要特定的硬件支持。

加速应用程序的三种主要方法包括库、OpenACC(添加指令,适用于高性能计算(HPC)等应用程序)以及编程语言。

  • 3 ways to accelerate applications:

    • Libraries
    • OpenACC (add directive, for applications like HPC)
    • Programming Languages
  • 库:
    使用预编程库是一种有效的应用程序加速方法。例如,NVIDIA Math Libraries(数学库)已经过优化,以充分利用GPU硬件,从而获得最大的性能增益。这些库旨在取代常见的CPU库,如OpenBLAS、LAPACK和Intel MKL,并以最小的代码更改加速NVIDIA GPU上的应用程序。
    通过使用这些库,开发人员可以利用经过高度优化和测试的代码,而无需从头开始编写所有算法。这不仅可以加速开发过程,还可以提高应用程序的性能和稳定性。

  • OpenACC:
    OpenACC是一种编程模型,允许开发人员通过添加简单的指令来指示编译器将代码区域从CPU迁移到GPU执行。这对于高性能计算(HPC)等应用程序特别有用,因为GPU在并行处理大量数据方面非常出色。
    使用OpenACC可以简化将代码从CPU迁移到GPU的过程,而无需深入了解底层的硬件和编程模型。然而,在某些情况下,可能需要手动调整和优化代码以获得最佳性能。

  • 编程语言:
    选择合适的编程语言也是加速应用程序的关键。例如,CUDA C和C++等编程语言在编写利用GPU硬件功能的代码时提供了更大的灵活性。这些语言允许开发人员直接控制GPU的内存和计算资源,从而实现更高的性能。
    然而,使用这些语言也需要开发人员具备更深入的硬件和编程知识。因此,在选择编程语言时,需要根据应用程序的需求和开发人员的技能水平进行权衡。

需要注意的是,以上三种方法并不是孤立的,而是可以相互结合使用的。例如,可以使用OpenACC指令来简化代码迁移到GPU的过程,并使用预编程库来加速特定的计算任务。同时,根据应用程序的需求和硬件环境选择合适的编程语言也是非常重要的。

DCGM

https://developer.nvidia.com/dcgm

https://on-demand.gputechconf.com/gtc/2018/presentation/s8505-gpu-monitoring-and-management-with-nvidia-data-center-gpu-manager-dcgm-v2.pdf

  • Note:
    • 监控 PCIE-RX —> H2D 带宽
    • Health Check
nvidia-smi
nvidia-smi
nvidia-smi --query-gpu=name --format=csv,noheader
OAM

OAM(Open Accelerator Memory Interface)是一个旨在标准化异构计算设备之间通信接口的开放协议。这个协议的目标是打破不同计算卡之间的通信壁垒,尤其是与NVIDIA的nvlink这样的封闭协议相比,OAM更强调开放性和兼容性。

  • OAM是一种异构计算设备的接口协议,对标nvlink. nvlink是封闭的协议,OAM是若干大厂共建的一个开放协议。

    • 目的:避免每一种卡都有自己的卡间通信标准,尽量做到 (除了NV的卡之外)任何厂家的计算卡都兼容
    • 技术层面, OAM 和 NVSWITCH (对应A100 这代) 基本是对等的
      • OAM:是 full connect 模式, 各卡独享约 ~80GB/s 带宽
        • full connect 的结构更为简单,有一些散热和能耗的优势
      • NV switch: 整个switch提供 600GB/s 带宽
      • 单机八卡时,OAM 和 NV switch 差不多;卡数少时 nvsiwtch 效率高
  • OAM的特点
    开放性:OAM是一个由多个大厂共同建设的开放协议,旨在实现不同厂商计算卡之间的兼容性。
    Full Connect模式:OAM采用了full connect的拓扑结构,意味着每个计算卡都可以直接与其他卡进行通信,而不需要经过中央交换机。这种结构为每个卡提供了约80GB/s的独享带宽。
    散热和能耗优势:由于full connect的结构相对简单,OAM可能在散热和能耗方面有一定的优势。

  • 与NVSWITCH的比较
    带宽:NVSWITCH(例如A100这代)作为一个中央交换机,可以为整个系统提供高达600GB/s的总带宽。但是,这个带宽是共享的,而OAM为每个卡提供了独享的带宽。
    效率:在单机多卡配置中,当卡数较少时,NVSWITCH的效率可能更高,因为它可以更有效地管理带宽的分配。然而,随着卡数的增加,OAM的full connect结构可能提供更高的总体性能和更低的延迟。
    兼容性:OAM的一个主要优势是其开放性,使得来自不同厂商的计算卡能够更容易地实现兼容。而NVSWITCH则主要适用于NVIDIA自家的GPU。

OAM作为一个开放的计算卡间通信协议,旨在提供与NVSWITCH类似的性能,同时强调兼容性和开放性。对于需要跨厂商兼容性的应用场景,OAM可能是一个有吸引力的选择。然而,具体选择哪种技术取决于具体的应用需求、硬件配置和成本考虑。

Nvidia Lectures

1.Course: Accelerating Applications with CUDA C/C++

课程网页

Writing Application Code for the GPU
nvidia-smi
cudaMallocManaged()
cudaDeviceSynchronize()
  
nvcc -arch=sm_70 -o hello-gpu 01-hello/01-hello-gpu.cu -run
  • code executed on the CPU is referred to as host code, and code running on the GPU is referred to as device code
void CPUFunction()
{
  printf("This function is defined to run on the CPU.\n");
}

__global__ void GPUFunction()
{
  printf("This function is defined to run on the GPU.\n");
}
// __global__表示CPU/GPU均可执行,必须返回void

int main()
{
  CPUFunction();
	// launch a kernel, provide an execution configuration
  GPUFunction<<<1, 1>>>();
  cudaDeviceSynchronize();
  // CPU等待GPU
}

At a high level, execution configuration allows programmers to specify the thread hierarchy for a kernel launch, which defines the number of thread groupings (called blocks), as well as how many threads to execute in each block.

NVIDIA CUDA Compiler, documentation

arch flag, virtual architecture features

CUDA Thread Hierarchy
  • Programming model: SIMT
    • 三层抽象:grid, block, thread

SIMT(Single Instruction, Multiple Threads)是一种编程模型

尤其在GPU计算中广泛应用。它引入了线程的概念,使得每个线程可以独立执行相同的指令,但可能处理不同的数据。这种模型适用于大规模数据并行计算,例如图形渲染和深度学习等应用。

在SIMT编程模型中,通常存在三层抽象:grid、block和thread。这三层抽象为程序员提供了一种灵活的方式来组织和管理线程。

Grid:Grid是最高层次的抽象,它表示一个完整的任务或工作负载。Grid可以包含多个block,每个block都是一个独立的执行单元,可以在GPU上的一个或多个SM(流多处理器)上并行执行。

Block:Block是Grid中的子集,它包含了一组可以并行执行的线程。Block内的线程可以共享相同的数据和内存空间,这使得它们之间的通信和数据共享变得相对容易。此外,block还可以被进一步划分为更小的线程组(如warp),以便在硬件层面上进行更有效的调度和执行。

Thread:Thread是SIMT编程模型中的基本执行单元。每个线程都执行相同的指令,但可能处理不同的数据。线程是轻量级的,并且可以在GPU上并行执行数以千计的线程。线程之间的通信和数据共享通常通过共享内存或原子操作来实现。

通过使用grid、block和thread这三层抽象,程序员可以更加灵活地组织和管理线程,以便更好地利用GPU的并行计算能力。例如,程序员可以根据任务的特点和数据的大小来设置grid和block的大小,以及线程的数量和调度方式,从而优化任务的执行效率和性能。

  • Kernel Execution

    • configuration ~ grid

    • Each block is executed by one SM and does not migrate.<

  • 54
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EwenWanW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值