NCCL源码解读5:拓扑识别感知整体思路总览

依据物理拓扑结构,来进行通信,可达到性能更优,这也是Nvidia NCCL的核心功能。

视频教程

2.1 NCCL拓扑识别感知总览 源码解读_哔哩哔哩_bilibili

NCCL拓扑识别的整体思路:

1、物理拓扑构建

2、通信路径计算(每个GPU/网卡到其它GPU,网卡的最优路径。)

3、逻辑拓扑构建(通信通道检索)

哈哈哈,整体思路是不是特别简单。就是先获取物理拓扑图,然后计算通信路径(方便逻辑拓扑构建),根据通信路径构建逻辑拓扑,例如ring,tree逻辑拓扑,指明哪个GPU和哪个GPU通信。

具体每个细节下次分享会讲,这次大家先留个映象。 

源码速递

源码位置:nccl-master\src\init.cc

1、物理拓扑构建:ncclTopoGetSystem()

2、通信路径计算:ncclTopoComputePaths()

3、逻辑拓扑构建(通信通道检索):ncclTopoCompute()

static ncclResult_t initTransportsRank(struct ncclComm* comm, struct ncclComm* parent = NULL) {

// 其它代码


// 获取系统的拓扑信息,并存储在comm的topo成员中  
NCCLCHECKGOTO(ncclTopoGetSystem(comm, &comm->topo), ret, fail);    

// 在已获取的拓扑中,计算GPU和NIC之间的路径  
NCCLCHECKGOTO(ncclTopoComputePaths(comm->topo, comm), ret, fail);    

// 根据计算结果,移除不可访问的GPU和未使用的NIC  
NCCLCHECKGOTO(ncclTopoTrimSystem(comm->topo, comm), ret, fail);  

// 在移除不可访问的组件后,重新计算路径  
NCCLCHECKGOTO(ncclTopoComputePaths(comm->topo, comm), ret, fail);  

// 初始化拓扑搜索  
NCCLCHECKGOTO(ncclTopoSearchInit(comm->topo), ret, fail);  

// 打印最终的拓扑结构,用于调试或信息展示  
NCCLCHECKGOTO(ncclTopoPrint(comm->topo), ret, fail);  

// 获取与当前GPU本地化的CPU亲和性,即哪些CPU与当前GPU通信效率最高  
NCCLCHECKGOTO(ncclTopoGetCpuAffinity(comm->topo, comm->rank, &comm->cpuAffinity), ret, fail);  

// 如果找到了与GPU匹配的CPU亲和性(即找到了可用的CPU集合)  
if (CPU_COUNT(&comm->cpuAffinity)) {  
    // 保存当前线程的CPU亲和性设置(可能是为了之后恢复)  
    sched_getaffinity(0, sizeof(cpu_set_t), &affinitySave);  
    // 将当前线程的CPU亲和性设置为与GPU匹配的CPU集合  
    sched_setaffinity(0, sizeof(cpu_set_t), &comm->cpuAffinity);  
}  

// 检查本地是否支持CollNet(NCCL的一种优化)  
if (collNetSupport(comm)) {  
    // 获取环境变量NCCL_COLLNET_ENABLE的值,决定是否启用CollNet  
    const char *collNetEnable = ncclGetEnv("NCCL_COLLNET_ENABLE");  
    if (collNetEnable != NULL) {  
        // 如果环境变量已设置,打印信息到日志或控制台  
        INFO(NCCL_ALL, "NCCL_COLLNET_ENABLE set by environment to %s.", collNetEnable);  
        // 如果环境变量值为"1",则启用CollNet支持  
        if (strcmp(collNetEnable, "1") == 0) {  
            comm->collNetSupport = 1;  
        }  
    }  
}  

  

// 初始化Nvls支持第三代NVSwitch系统(NVLink4)
NCCLCHECK(ncclNvlsInit(comm));  


// 初始化环图结构,用于表示环形的通信模式  
memset(&ringGraph, 0, sizeof(struct ncclTopoGraph));  
ringGraph.id = 0;  
ringGraph.pattern = NCCL_TOPO_PATTERN_RING;  
ringGraph.minChannels = 1;  
ringGraph.maxChannels = MAXCHANNELS/2;  

// 在已获取的拓扑中,计算环图的通信信息  
NCCLCHECKGOTO(ncclTopoCompute(comm->topo, &ringGraph), ret, fail);  

// 打印环图的拓扑结构,用于调试或信息展示  
NCCLCHECKGOTO(ncclTopoPrintGraph(comm->topo, &ringGraph), ret, fail); 

// 其它代码

} 

下次分享:

物理拓扑构建

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
NVIDIA NCCL(NVIDIA Collective Communications Library)是一种用于高性能并行计算的库,特别适用于多GPU系统中的并行通信操作。如果你想学习NCCL源码,我可以给你一些建议: 1. 先了解基本概念:在开始研究NCCL源码之前,确保你对并行计算和通信操作有基本的了解。理解NCCL的设计目标和背后的原理会有助于你更好地理解源码。 2. 寻找源码NCCL源码可以在NVIDIA的开源GitHub存储库中找到。你可以在https://github.com/NVIDIA/nccl 上找到最新的代码。 3. 阅读文档:NVIDIA提供了NCCL的官方文档,其中包含了详细的API文档和使用指南。在阅读源码之前,先浏览一遍文档,了解库的功能和使用方式,这将有助于你更好地理解源码中的细节。 4. 逐步阅读源码:开始时,可以选择从简单的功能开始阅读,逐步深入到更复杂的部分。从整体架构入手,了解主要的数据结构和函数调用关系。然后,选择一个具体的功能或算法,深入研究相关的源代码。 5. 调试和实践:通过在实际应用中使用NCCL库,你可以更好地理解源码。尝试使用NCCL库进行一些简单的通信操作,并通过调试器进行源码跟踪,观察库的行为和内部工作原理。 6. 参考资料和社区支持:除了官方文档和源码,你还可以参考一些相关的学术论文、博客文章和社区讨论,这些资源可以帮助你更好地理解NCCL的设计和实现。 希望这些建议对你学习NCCL源码有所帮助!如果你有其他问题,请随时提问。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值