Skip to content

CUDA Multi GPU Parallel Computing Report

VodkaSoul edited this page Nov 12, 2019 · 2 revisions

基于 NVIDIA Multi-GPU 技术的 CUDA 多 GPU 并行计算可行性及其原理探究

分布式 GPU 加速运算基本原理

  • GPU 加速集群,使用多个计算节点(即多节点多设备)
  • MPI(消息传递接口)与 CUDA 是完全兼容的,可以使用 CUDA-aware MPI 支持 GPU 在不同节点上移动数据,加上GPUDirectRMDA使得GPU间通信带宽更高,延迟更低。

CUDA 多 GPU 并行可行性分析

  • 使用场景: 单 GPU 内存或处理性能不足,采用 GPU 并行的方式增大应用程序的吞吐量。
  • CUDA 提供的相关接口: 首先显示指定哪个 GPU 是当前所有 CUDA 运算的目标:cudaSetDevice,然后可以设定不同 GPU 间的访问(权限)以支持 GPU 间的数据通信,具体计算步骤与单 GPU 情形类似。
  • GPU 间通信: 点对点访问开启后,可直接使用内存复制(前提:多个 GPU 通过 PCIe 总线连接到 host),PCIe 总线支持任何两个节点间的双全工通信。
  • 例子: 有限方差的方法求解二维波动方程 。

cublasXt API of cuBLAS (CUDA6.0 后支持)

  • 该 API 仅支持 64 位平台

  • 该 API 能够自动负责在指定的 GPU 之间分配内存,并在它们之间分配计算负载,还可支持 CPU 与 GPU 混合运算

  • 原理:为了能够在多个GPU之间共享计算负载,cublasXt API 使用了切片策略:每个矩阵都可被用户划分为 BlockDim x BlockDim 的正方形切片。各个切片的静态调度策略:每个 GPU 都会创建一个 CPU 线程,并负责执行适当的内存传输和 cuBLAS 操作,以计算出所有的切片负责。从性能的角度来看,由于采用了这种静态调度策略,每个 GPU 的计算能力和 PCI 带宽最好相同。

  • 下图说明了 3 个GPU之间的图块分布。为了从 C 计算第一个图块 G0,负责 GPU0 的 CPU 线程 0 必须以流水线方式从 A 的第一行中加载 3 个图块,并从 B 的第一个列中加载图块,以便与内存传输,计算和求和重叠结果进入 C 的第一个图块 G0,然后移至下一个图块 G0(当图块尺寸不是 C 尺寸的精确倍数时,某些图块会部分填充在右边界或底边界上,但是,当所有 GPU 都没有相同数量的不完整切片需要处理时,它仍然可能导致一些负载不平衡)

    当一个或多个矩阵位于某些 GPU 设备上时,将应用相同的切片方法和工作负载共享。在这种情况下,内存传输是在设备之间完成的。

  • GPU-CPU 混合计算:对于 size 非常大的的问题,cublasXt API 可以将某些计算分配到 CPU 上。如函数cublasXtSetCpuRoutine()cublasXtSetCpuRatio(),它从底部和右侧获取的结果矩阵的进行比较维度,之后,在缩小后的结果矩阵上完成 GPU 切片,其余的部分由 CPU 计算完成。

  • 重要 API:

    //为句柄设置gpu
    cublasXtDeviceSelect(cublasXtHandle_t handle,int nbDevices,int deviceId [])
    //设置矩阵平铺的块大小
    cublasXtSetBlockDim(cublasXtHandle_t handle,int  blockDim)