Akhil Langer, Seth Howell, Jim Dinan, Nvidia | GTC Spring 2023
特点:
普遍使用的模型,但存在问题:
* 在关键路径中存在卸载延迟(Offload latencies in critical path)。
* 通信未重叠(Communication is not overlapped)。
* 隐藏这些延迟会增加代码复杂性。
* 不隐藏延迟会限制强扩展性。
特点:
* 在GPU上进行计算。
* 由GPU发起通信。
优点:
* 消除了卸载延迟(Eliminates offload latencies)。
* 计算和通信重叠(Compute and communication overlap)。
* 通过线程隐藏延迟(Latencies hidden by threading)。
* 更易于用内联通信表达算法(Easier to express algorithms with inline communication)。
目标: 在提升性能的同时,简化编程。
OpenSHMEM,为NVIDIA GPU集群上的最佳性能而适配
功能: 将集群中多个GPU的内存聚合到一个分布式全局地址空间中。
put、get、原子API进行数据访问。通信与CUDA执行模型集成:
可与CPU OpenSHMEM或MPI库结合使用,用于主机内存通信。
独立分区聚合到全局地址空间
对称对象在每个PE上以相同大小集体分配。
nvshmem_malloc(...)cudaMalloc(...)读: nvshmem_get(...)
nvshmem_put(...)nvshmem_atomic_add(...)nvshmem_quiet()nvshmem_fence()nvshmem_barrier()nvshmem_wait_until(...)使用第四代NVLink无缝扩展至256个GPU
NVSHMEM无缝扩展:
内部使用CUDA IPC和cuMem API将对等PE的对称内存映射到虚拟地址空间。
nvshmem_put/get on device → load/storenvshmem_put/get_on_stream → cudaMemcpyAsyncnvshmem_ptr direct pointer bypass → kernel direct load/store理论对等体双向带宽 (GB/s)
理论网络注入 + 弹出带宽每GPU (GB/s)
* 100Gb ConnectX-5 (DGX V100):25
* 200Gb ConnectX-6 (DGX A100):50
* 400Gb ConnectX-7 (DGX H100):100
_global_ void stencil_single_step(float *u, float *v, ...) {
int ix = get_ix(blockIdx, blockDim, threadIdx);
int iy = get_iy(blockIdx, blockDim, threadIdx);
compute(u, v, ix, iy);
// Thread-level data communication API
if (iy == 1)
nvshmem_float_p(u+(ny*1)*nx+ix, u[nx+ix], top_pe);
if (iy == ny)
nvshmem_float_p(u+ix, u[ny*nx+ix], bottom_pe);
}
for (int iter = 0; iter < N; iter++) {
swap(u, v);
stencil_single_step<<<..., stream>>>(u, v, ...);
nvshmem_barrier_all_on_stream(stream);
}
_global_ void stencil_single_step(float *u, float *v, ...) {
int ix = get_ix(blockIdx, blockDim, threadIdx);
int iy = get_iy(blockIdx, blockDim, threadIdx);
compute(u, v, ix, iy);
// Thread block-level communication API
int boffset = get_block_offet(blockIdx, blockDim);
if (blockIdx.y == 0)
nvshmemx_float_put_nbi_block(u+(ny*1)*nx+boffset, u+nx+boffset, blockDim.x, top_pe);
if (blockIdx.y == (blockDim.y-1))
nvshmemx_float_put_nbi_block(u+boffset, u+ny*nx+boffset, blockDim.x, bottom_pe);
}
for (int iter = 0; iter < N; iter++) {
swap(u, v);
stencil_single_step<<<..., stream>>>(u, v, ...);
nvshmem_barrier_all_on_stream(stream);
}
_global_ void stencil_multi_step(float *u, float *v, int N, int *sync, ...) {
int ix = get_ix(blockIdx, blockDim, threadIdx);
int iy = get_iy(blockIdx, blockDim, threadIdx);
for (int iter = 0; iter < N; iter++) {
swap(u, v);
// Thread block-level data exchange (assume even/odd iter buffering)
int boffset = get_block_offet(blockIdx, blockDim);
if (blockIdx.y == 0)
nvshmemx_float_put_nbi_block(u+(ny*1)*nx+boffset, u+nx+boffset, blockDim.x, top_pe);
if (!((blockIdx.y == (blockDim.y-1))))
nvshmemx_float_put_nbi_block(u+boffset, u+ny*nx+boffset, blockDim.x, bottom_pe);
this_grid.sync();
if ((!itid) nvshmem_barrier(); // Be aware of synchronization costs. Best synchronization approach is application dependent!
this_grid.sync();
}
}
更多详情:https://github.com/NVIDIA/multi-gpu-programming-models
NVSHMEM CPU发起的在CUDA流和图上入队的操作
grid.sync())的延迟可能比核函数启动延迟更长。确保使用设备侧核间同步时的进度
| NVSHMEM 用法 | CUDA 核函数启动 |
|---|---|
| 设备发起的通信 | 执行配置语法 <<<...,>>> 或启动API |
| 设备发起的同步 | nvshmemx_collective_launch |
CUDA Graphs (CUDA图):
NVSHMEM可与Graphs组合使用:
通过基于属性的初始化例程启用
MPI:
使用MPI_COMM_WORLD初始化NVSHMEM。
MPI_Init(&argc, &argv);
MPI_Comm mpi_comm = MPI_COMM_WORLD;
nvshmemx_init_attr_t attr;
attr.mpi_comm = &mpi_comm;
nvshmemx_init_attr(NVSHMEMX_INIT_WITH_MPI_COMM, &attr);
mype_node = nvshmem_team_my_pe(NVSHMEMX_TEAM_NODE);
CUDA_CHECK(cudaSetDevice(mype_node));
OpenSHMEM:
使用SHMEM默认上下文初始化NVSHMEM。
shmem_init();
nvshmemx_init_attr_t attr;
nvshmemx_init_attr(NVSHMEMX_INIT_WITH_SHMEM, &attr);
mype_node = nvshmem_team_my_pe(NVSHMEMX_TEAM_NODE);
CUDA_CHECK(cudaSetDevice(mype_node));
自 NVSHMEM 2.5.0 / GTC Spring 2022 以来新增的特性:
HPC SDK 集成
CMake 构建系统 (CMake build system)
DMABUF 支持
Slingshot-11 支持
与 Mellanox NICs 更紧密的集成
内核可以直接执行:
并行度显著提升,从而提高了吞吐量。
在 2kB 和 16kB 传输大小下的全带宽
将多个 NVSHMEM "p" 操作合并为一个工作请求
* IBGDA 合并 (IBGDA Coalescing) 在 128 个 CTA 时达到 1935 MOPS 的消息速率,远高于 IBRC 的 180 MOPS 和 IBGDA 的 1.7 MOPS。
改进了可移植性和可用性
* HPC_SDK 在多个平台上分发 NVSHMEM 及其他兼容软件包。
* HPC_SDK 中使用的 NVSHMEM 二进制包的近期更改通常也很有用。
* NVSHMEM 现在支持 CUDA 次要版本兼容性。
* 编译器限制:所有静态链接的部分必须使用最旧的编译器版本构建。
模块化传输从主要的 NVSHMEM 库中移除了特定于传输的要求。
模块化引导接口已得到改进。
改进了延迟
* 设备 API 实现:
* P2P 内存复制 (内联)
* 远程通信 (未内联)
* 集合 API 实现 (未内联)
NVSHMEM_ENABLE_ALL_DEVICE_INLINING = 0/1。__forceinline__ 限定符启用内联。nvshmem_put + nvshmem_fence + nvshmem_signal。拓扑感知算法:
广播:
规约 (Reduce):
扁平化的 All-to-all:
拓扑感知 All-to-all:
性能提高 95%。
多节点多 GPU:使用 NVIDIA cuFFTMp FFTs 进行规模化计算。
https://developer.nvidia.com/blog/multi-node-multi-gpu-using-nvidia-cufftmp-ffts-at-scaleJAX + cuFFTMp:
GROMACS + cuFFTMp:
GROMACS 中还存在其他可能受益于 NVSHMEM 的通信模式:
原型版本使用 NVSHMEM 进行 PP halo 交换通信。
传统 HPL:
HPL + NVSHMEM:
本节详细介绍了 Grace Hopper 超级芯片架构及其在 NVSHMEM 中的支持。
第四代 NVLink 进一步增强了互联性能。
本节阐述了 NVSHMEM 内存空间和上下文,以实现对 Grace CPU 内存的访问并改进通信管理。
内存空间 (Memory Spaces)
上下文 (Contexts)
nvshmem_team_split 创建 Team,其中包含内存空间参数 team_config_t 和 Memory Space。Memory Space 包含 Symmetric Heap 和 Registered User Buffer(s)。nvshmem_ctx_create 创建 Context,与 Resources 通过 ctx_options_t 关联。Context 处理 NVSHMEM RMA and AMO Operations Quiet and Fence。NVSHMEM 是一个用于 NVIDIA GPU 集群的 PGAS (Partitioned Global Address Space) 库。
NVSHMEM 可无缝扩展,支持:
NVSHMEM 提供 Stream/Graph、GPU 内核启动和 CPU 启动的 API。
NVSHMEM 的最新发布信息和关键特性。
新特性 (New Features):
实现特性 (Implementation Features):