用户缓冲区注册

用户缓冲区注册是一项功能,允许 NCCL 直接通过用户缓冲区发送/接收/操作数据,而无需额外的内部复制(零复制)。它可以加速集体操作并大大减少资源使用量(例如,#通道使用量)。NCCL 提供了两种注册用户缓冲区的方法;一种是CUDA Graph 注册,另一种是本地注册。NCCL 要求,对于所有 NCCL 通信函数调用(例如,allreduce、sendrecv 等),如果通信器中的任何 rank 将注册缓冲区传递给 NCCL 通信函数,则同一通信器中的所有其他 rank 都必须传递其注册缓冲区;否则,混合使用注册缓冲区和非注册缓冲区可能会导致未定义的行为。

IB Sharp 缓冲区注册

NCCL 2.21.x 支持 IB Sharp 缓冲区注册,任何支持 IB Sharp 算法的 NCCL 集体操作都可以从中受益,例如 allreduce、reducescatter 和 allgather。目前,NCCL 仅支持每个节点包含 1 个 rank 的通信器的 IB Sharp 缓冲区注册,并且注册可以将 NCCL SM 使用量减少到 1。

要通过 CUDA graph 启用 IB Sharp 缓冲区注册

  • 使用任何 CUDA 分配器(例如,cudaMalloc/ncclMemAlloc)分配发送和接收缓冲区
  • 使用 CUDA graph 启动 NCCL 集体操作

要通过本地注册启用 IB Sharp 缓冲区注册

  • 使用任何 CUDA 分配器(例如,cudaMalloc/ncclMemAlloc)分配发送和接收缓冲区
  • 使用 ncclCommRegister 为通信器中的每个 rank 注册发送和接收缓冲区
  • 启动 NCCL 集体操作

通用缓冲区注册

自 2.23.x 起,NCCL 支持节点内缓冲区注册,它针对所有点对点节点内通信,并带来更少的内存访问、更少的 SM 使用量和性能提升。在开始时通过 ncclCommRegister 注册缓冲区或应用 CUDA graph 都可以为 NCCL 集体操作和 sendrecv 启用节点内缓冲区注册。注册的缓冲区可以通过旧版 cuda API(例如,cudaMalloc)以及 VMM API(例如,cuMem*ncclMemAlloc)分配。但是,强烈建议使用 VMM 分配的缓冲区,因为它比失败和中止期间的旧版缓冲区更安全。

内存分配器

为方便起见,NCCL 提供了 ncclMemAlloc 函数,以帮助用户通过 VMM API 分配缓冲区,该缓冲区稍后可用于 NCCL 注册。它仅为 NCCL 设计,因此不建议在应用程序中的任何地方使用 ncclMemAlloc 分配的缓冲区。对于高级用户,如果您想为 NVLS 缓冲区注册创建自己的内存分配器,则该分配器需要满足以下要求

  • 在支持的 GPU 上,使用共享标志 CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTORCU_MEM_HANDLE_TYPE_FABRIC 分配缓冲区。
  • 缓冲区大小是多播建议粒度的倍数 (即 cuMulticastGetGranularity(…, CU_MULTICAST_GRANULARITY_RECOMMENDED))
  • 缓冲区头地址至少与多播最小粒度对齐 (即 cuMulticastGetGranularity(…, CU_MULTICAST_GRANULARITY_MINIMUM))