AllGather-PAT算法
根据前三篇,可以得知:如果仅想要查看一个算法和其余算法的不同点,着重入手的地方为如下三处
- 算法成本权重计算
- 预建链
- 算子实现
未完,不一定有续
NCCL 中 AllGather 自动选择 PAT 算法的条件
PAT 算法启用的必要条件
1. 硬件要求
GPU 架构要求
- 最低计算能力: SM 6.0 或更高(Pascal 架构及以上)
- 代码位置 :
src/graph/tuning.cc:204
cpp
if (comm->minCompCap < 60) return 0; // Need SM60 or higher for CUDA atomics
拓扑要求
- 每节点 GPU 数量 : 必须是 1 GPU/节点(这是最关键的限制)
- 代码位置 :
src/graph/tuning.cc:206
cpp
if (comm->nNodes != comm->nRanks) return 0; // PAT only supports 1 GPU per node
网络设备要求
- 网络设备类型 : 必须是 HOST 类型(不支持网络设备卸载)
- 代码位置 :
src/graph/tuning.cc:207
cpp
if (comm->netDeviceType != NCCL_NET_DEVICE_HOST) return 0; // PAT doesn't support net device offload
2. 协议要求
- 协议 : 只支持 NCCL_PROTO_SIMPLE
- 代码位置 :
src/graph/tuning.cc:282
cpp
if ((coll == ncclFuncReduceScatter || coll == ncclFuncAllGather)
&& a == NCCL_ALGO_PAT && (p != NCCL_PROTO_SIMPLE || ncclPatEnable(comm) == 0)) continue;
3. 环境变量(可选)
虽然要求不通过环境变量强制指定,但了解相关参数有助于理解:
NCCL_PAT_ENABLE: 默认值为 2(自动),可设为 0(禁用)或 1(强制启用)- 代码位置 :
src/graph/tuning.cc:201-209
PAT 算法的性能模型
带宽计算
- 基础带宽 : 从拓扑图获取
graphs[NCCL_ALGO_PAT]->bwIntra - 效率因子 : 乘以 0.75
- 代码位置 :
src/graph/tuning.cc:310
cpp
if (a == NCCL_ALGO_PAT) busBw *= .75;
延迟计算(AllGather)
- 基础延迟: 8.0 μs(所有协议)
- 额外延迟 :
log2(nNodes) * (interLat/3.5) + nRanks * 2.8 - 代码位置 :
src/graph/tuning.cc:396-400
cpp
if (a == NCCL_ALGO_PAT) {
if (coll == ncclFuncAllGather || coll == ncclFuncReduceScatter) {
comm->latencies[coll][a][p] += log2i(nNodes) * (interLat/3.5) // Log latency
+ nRanks * 2.8; // Still a linear part
}
}
硬件延迟(SIMPLE 协议)
- NVLINK: 4.0 μs
- PCI: 4.0 μs
- NET: 14.0 μs
- 代码位置 :
src/graph/tuning.cc:147-166
算法选择逻辑
成本计算公式
cpp
*time = lat * latCount + nBytes / (1000 * bw);
选择最优算法
在 topoGetAlgoInfo() 中,遍历所有算法和协议组合,选择时间最短的:
cpp
for (int a=0; a<NCCL_NUM_ALGORITHMS; a++) {
for (int p=0; p<NCCL_NUM_PROTOCOLS; p++) {
if (table[a][p] >= 0.0 && table[a][p] < minTime) {
algorithm = a;
protocol = p;
minTime = table[a][p];
}
}
}
如何让 AllGather 选择 PAT 算法
推荐配置
硬件拓扑
拓扑结构: 多节点,每节点 1 GPU
示例: 4 节点 × 1 GPU = 4 个 GPU 总计
GPU 要求
GPU 架构: Pascal (SM 6.0) 或更高
推荐: Volta (SM 7.0+), Ampere (SM 8.0+), Hopper (SM 9.0+)
网络配置
网络类型: 主机端网络(非 GPU Direct RDMA 卸载)
网络设备: InfiniBand 或高速以太网
CUDA 版本
CUDA Runtime: 任意版本(PAT 不需要特定 CUDA 版本)
Driver: 支持对应 GPU 架构的驱动
数据大小建议
PAT 算法在以下情况下性能最优:
- 中等到大数据量: 建议 > 64 KB
- 多节点场景: 节点数越多,PAT 的对数延迟优势越明显
示例配置
配置 1: 4 节点 × 1 GPU(最理想)
cpp
// 硬件拓扑
nRanks = 4
nNodes = 4 // 每节点 1 GPU
minCompCap = 70 // Volta 或更高
netDeviceType = NCCL_NET_DEVICE_HOST
// AllGather 调用
size_t count = 1024 * 1024; // 1M 元素
ncclAllGather(sendbuff, recvbuff, count, ncclFloat32, comm, stream);
配置 2: 8 节点 × 1 GPU
cpp
// 硬件拓扑
nRanks = 8
nNodes = 8 // 每节点 1 GPU
minCompCap = 80 // Ampere
netDeviceType = NCCL_NET_DEVICE_HOST
// AllGather 调用
size_t count = 512 * 1024; // 512K 元素
ncclAllGather(sendbuff, recvbuff, count, ncclFloat32, comm, stream);
PAT 算法何时会被选择
性能优势场景
PAT 算法在以下情况下会胜出:
-
多节点场景(每节点 1 GPU)
- PAT 的对数延迟
log2(nNodes)优于 Ring 的线性延迟nRanks-1 - 节点数越多,优势越明显
- PAT 的对数延迟
-
中等数据量
- 延迟占主导时,PAT 的对数延迟优势明显
- 太小的数据量可能选择 LL 协议的 Ring
- 太大的数据量带宽占主导,可能选择其他算法
-
主机端网络
- 不使用 GPU Direct RDMA 卸载
- 网络设备类型为 HOST
性能对比示例
假设 8 节点 × 1 GPU,数据量 1 MB:
| 算法 | 延迟计算 | 带宽 | 总时间 |
|---|---|---|---|
| PAT | 8.0 + log2(8)*(interLat/3.5) + 8*2.8 ≈ 35 μs |
busBw * 0.75 |
较优 |
| Ring | (8-1) * interLat ≈ 98 μs |
busBw |
延迟较高 |
验证方法
查看日志
启用 NCCL 调试日志查看选择的算法:
bash
export NCCL_DEBUG=INFO
export NCCL_DEBUG_SUBSYS=TUNING
运行程序后会看到类似输出:
AllGather: 4194304 Bytes -> Algo PAT proto SIMPLE channel{Lo..Hi}={0..15}
代码验证点
在 scheduleCollTasksToPlan() 中会打印选择的算法:
cpp
INFO(NCCL_TUNING, "%s: %ld Bytes -> Algo %s proto %s channel{Lo..Hi}={%d..%d}",
ncclFuncToString(task->func), task->count * ncclTypeSize(task->datatype),
ncclAlgoToString(task->algorithm), ncclProtoToString(task->protocol),
devWork->channelLo, devWork->channelHi);
总结
要让 AllGather 自动选择 PAT 算法,需要满足:
必要条件(缺一不可)
- ✅ GPU 架构: SM 6.0+(Pascal 或更高)
- ✅ 拓扑结构: nNodes == nRanks(每节点 1 GPU)
- ✅ 网络类型: netDeviceType == NCCL_NET_DEVICE_HOST
- ✅ 协议: NCCL_PROTO_SIMPLE
- ✅ PAT 启用: ncclPatEnable(comm) == 1(默认满足)
性能优势条件
- ✅ 节点数: 4+ 节点(对数延迟优势明显)
- ✅ 数据量: 中等到大(64 KB - 几 MB)
- ✅ 网络: 高速网络(InfiniBand 等)
典型场景
最理想: 8 节点 × 1 GPU/节点,使用 InfiniBand 网络,AllGather 1 MB 数据,Volta 或更高架构的 GPU。