从“自己搬砖”到“指挥别人搬砖”:DUSHMEM库如何让多卡通信更简单
如果你写过GPU程序一定遇到过这样的场景你手上有8块DCU每块卡上都跑着一个进程PEProcessing Element你想让0号卡上的数据能被1号卡直接读取——怎么做最直接的办法是0号卡把数据从显存拷到CPU内存1号卡再从CPU内存拷到自己的显存。数据兜了一大圈CPU在中间当“搬运工”延迟高、带宽低CPU还被占着干不了别的活。有没有更好的办法有。让DCU之间直接通信绕过CPU。DUSHMEM就是干这个的。一、DUSHMEM是什么DUSHMEM的全称是DCU Unified Shared Memory是DTK中的一套DCU集合通信库。它提供了一种叫PGASPartitioned Global Address Space分区全局地址空间的并行编程模型。听起来很唬人拆开看就明白了。“分区”每个PE进程都有自己的内存这些内存是“分区”的——各自管各自的。“全局地址空间”虽然内存是分区的但从编程角度看所有PE的内存构成了一个统一的“全局地址空间”。你可以用dushmem_ptr拿到远程PE上某个变量的地址【7†L19】然后像访问本地内存一样读写它。换句话说DUSHMEM让每个PE都能直接读写其他PE的内存不需要CPU插手。这和之前讲的HIP Runtime API有什么不同HIP Runtime API解决的是“单块DCU上怎么写程序”——怎么分配显存、怎么启动Kernel、怎么管理流。DUSHMEM解决的是“多块DCU之间怎么通信”——怎么让数据在卡之间高效流动、怎么让多卡协同干活。一个管“单卡编程”一个管“多卡通信”两者是互补的关系。二、核心概念PE、对称内存、Team要理解DUSHMEM先记住三个概念PEProcessing Element就是DUSHMEM里的一个进程。每个PE有一个唯一的编号从0开始用dushmem_my_pe()查询当前PE的编号【7†L17】用dushmem_n_pes()查询总共有多少个PE【7†L18】。对称内存Symmetric Memory这是一块特殊的内存区域所有PE都能远程访问。用dushmem_malloc分配的内存就是对称内存【7†L24】——你在0号卡上分配一块内存1号卡也能通过DUSHMEM API读写它。Team一组PE的集合。DUSHMEM的集体通信如dushmem_barrier、dushmem_broadcast都是基于Team进行的【7†L28】。三、最简示例8张卡环形传数据光说概念太抽象看个完整例子【7†L9-L10】#includedushmem.h#includedushmemx.h__global__voidsimple_shift(int*destination){intmypedushmem_my_pe();// 我是几号卡intnpesdushmem_n_pes();// 一共几张卡intpeer(mype1)%npes;// 我要发给谁下一张卡dushmem_int_p(destination,mype,peer);// 把我的ID写到peer的destination里}intmain(){dushmem_init();// 初始化DUSHMEM【7†L13】intmype_nodedushmem_team_my_pe(DUSHMEMX_TEAM_NODE);hipSetDevice(mype_node);// 每个PE绑定一块DCUhipStream_t stream;hipStreamCreate(stream);int*destination(int*)dushmem_malloc(sizeof(int));// 分配对称内存【7†L24】// 启动Kernel每个PE把自己的ID写到下一张卡的destination里simple_shift1,1,0,stream(destination);dushmemx_barrier_all_on_stream(stream);// 等待所有通信完成【7†L27】intmsg;hipMemcpyAsync(msg,destination,sizeof(int),hipMemcpyDeviceToHost,stream);hipStreamSynchronize(stream);// 验证结果我收到的是上一张卡发来的IDintexpected(dushmem_my_pe()-1dushmem_n_pes())%dushmem_n_pes();printf(PE %d: received %d, expected %d\n,dushmem_my_pe(),msg,expected);dushmem_free(destination);// 释放对称内存【7†L24】dushmem_finalize();// 退出DUSHMEM【7†L12】return0;}这段代码在做什么8张卡每张卡上跑一个PE。每个PE把自己的编号写到下一张卡的destination里。最后每张卡都收到了上一张卡发来的编号【7†L11】。注意一个关键细节destination是用dushmem_malloc分配的——这意味着它在所有PE上都是对称的。0号卡的destination在1号卡上通过dushmem_ptr拿到地址后可以直接访问【7†L19】。这就是PGAS模型的精髓远程内存像本地内存一样访问。四、API分类四大金刚DUSHMEM的API可以分成四类【7†L7-L59】1. 初始化和查询——告诉DUSHMEM“我准备好了”dushmem_init()初始化DUSHMEM库所有PE必须调用【7†L13】dushmem_finalize()退出DUSHMEM释放资源【7†L12】dushmem_my_pe()/dushmem_n_pes()查询PE编号和总数【7†L17-L18】dushmem_ptr()获取远程PE上某个对称地址的本地指针【7†L19】dushmem_init是集体操作——所有PE必须一起调用不能有的调有的不调。dushmem_finalize同理【7†L12】。2. 内存管理——在“共享内存”里划地盘dushmem_malloc(size)从对称堆里分配一块内存【7†L24】dushmem_calloc(count, size)分配并清零【7†L26】dushmem_free(ptr)释放对称内存【7†L24】dushmem_align(alignment, size)按指定对齐分配【7†L24】这些也是集体操作——所有PE必须用相同的参数调用【7†L25】。为啥因为DUSHMEM需要在所有PE上维护一致的对称内存布局。3. 点对点通信——直接“喊话”点对点通信是DUSHMEM最核心的能力一个PE直接读写另一个PE的内存。Put写把数据从本地写到远程【7†L42】dushmem_int_put(dest,source,nelems,pe);// 把source写到pe的dest里dushmem_int_p(dest,value,pe);// 单元素的极低延迟put【7†L44】dushmem_int_iput(dest,source,dst,sst,nelems,pe);// 带步长的put【7†L45】Get读从远程把数据读到本地【7†L46】dushmem_int_get(dest,source,nelems,pe);// 从pe的source读到本地的destdushmem_int_g(source,pe);// 单元素的极低延迟get直接返回值【7†L48】dushmem_int_iget(dest,source,dst,sst,nelems,pe);// 带步长的get【7†L49】原子操作多PE同时读写同一块内存时保证数据一致性【7†L50-L58】dushmem_int_atomic_fetch_add(dest,value,pe);// 原子地读-加-写dushmem_int_atomic_compare_swap(dest,cond,value,pe);// 原子比较交换【7†L51】dushmem_int_atomic_fetch_and(dest,value,pe);// 原子位与【7†L55】dushmem_int_atomic_fetch_or(dest,value,pe);// 原子位或【7†L56】dushmem_int_atomic_fetch_xor(dest,value,pe);// 原子位异或【7†L58】原子操作在分布式计数器、锁、累加器等场景中非常有用——多个PE同时更新同一个变量不会出现数据竞争。4. 集合通信——大家一起“开会”当所有PE需要一起做事时用集合通信【7†L27-L41】dushmem_barrier_all()所有PE同步等到大家都到了再继续【7†L27】dushmem_barrier(team)指定Team内的PE同步【7†L28】dushmem_broadcast(dest, source, nelems, root)从root PE把数据广播给所有人【7†L33】dushmem_alltoall(dest, source, nelems)所有人都给所有人发数据【7†L31】dushmem_reduce(dest, source, nreduce, OP)所有PE的数据做归约求和、求最大等【7†L37】注意barrier和sync的区别【7†L29】dushmem_barrier保证所有远程写操作完成是“硬同步”dushmem_sync只保证本地写操作完成不保证远程写操作完成是“软同步”五、在DCU上跑Device端API上面列的所有API都有Device端版本——也就是说你可以在Kernel里直接调用DUSHMEM的通信函数【7†L17-L58】。比如在Kernel里这样写__global__voidmy_kernel(int*data){intmypedushmem_my_pe();// 在GPU上也能调用intpeer(mype1)%dushmem_n_pes();dushmem_int_p(data,mype,peer);// 在GPU上直接发数据给另一张卡}这意味着通信逻辑可以写在Kernel内部而不需要回到CPU端发起通信。对于需要细粒度通信的算法比如迭代式求解器、图计算这能大幅减少CPU参与降低延迟。但有一个重要限制如果Kernel里用了DUSHMEM的同步或集合通信API如dushmem_barrier、dushmem_barrier_all必须用dushmemx_collective_launch启动不能用普通的hipLaunchKernel【7†L22-L23】。因为这类API需要所有PE协同普通启动方式无法保证这种协同性。六、与MPI的对比为什么需要DUSHMEM如果你熟悉MPIMessage Passing Interface可能会问“DUSHMEM和MPI有什么区别MPI不是也能做多卡通信吗”核心区别在于通信模式MPI是“双边”的发送方调用MPI_Send接收方调用MPI_Recv两方必须配合。DUSHMEM是“单边”的发送方直接put到接收方的内存接收方完全不需要参与。单边通信的好处是解耦——发送方可以随时发数据接收方不需要提前准备好接收操作。这在异步计算、动态负载均衡等场景中非常有优势。更重要的是DUSHMEM可以和MPI混合使用【7†L11-L12】。如果你想在节点内部用DUSHMEM做高速通信、节点之间用MPI完全可以MPI_Init(argc,argv);MPI_Comm_rank(MPI_COMM_WORLD,rank);dushmemx_init_attr_t attr;attr.mpi_commMPI_COMM_WORLD;dushmemx_init_attr(DUSHMEMX_INIT_WITH_MPI_COMM,attr);// 基于MPI初始化DUSHMEM【7†L14】// ... 混合使用MPI和DUSHMEM ...dushmem_finalize();MPI_Finalize();这种灵活性让现有MPI应用可以逐步迁移到DUSHMEM而不需要推倒重来。七、环境变量调优的“旋钮”DUSHMEM提供了丰富的环境变量来控制运行时行为【7†L59-L64】DUSHMEM_SYMMETRIC_SIZE每个PE的对称堆大小默认1GB【7†L59】DUSHMEM_REMOTE_TRANSPORT选择远程传输协议默认ibrcInfiniBand RC【7†L62】DUSHMEM_HCA_LIST指定使用哪些InfiniBand网卡【7†L63】DUSHMEM_IB_ENABLE_IBGDA启用IBGDAInfiniBand GPU Direct Async功能【7†L64】DUSHMEM_DEBUG开启调试信息【7†L60】这些变量让你可以在不重新编译的情况下调整DUSHMEM的行为——比如在调试时打开日志、在生产环境调大对称堆大小。八、总结回到开头的问题多卡通信为什么难因为数据在卡之间搬动需要有人协调——谁来发、谁来收、什么时候发、什么时候收。传统方式让CPU当“中间人”慢且占资源。DUSHMEM的思路是让DCU自己管自己。用对称内存让所有PE共享一个逻辑上的全局地址空间用put/get实现单边通信接收方不需要参与用原子操作保证多PE同时访问时的数据一致性用集合通信实现PE之间的协同用Device端API让通信逻辑直接在Kernel里完成如果说HIP Runtime API解决的是“怎么让一块DCU干活”那DUSHMEM解决的就是“怎么让一堆DCU一起干活”——而且是高效地、直接地、不需要CPU插手地一起干活。对于多卡编程的开发者来说DUSHMEM提供了一套顺手且强大的工具。从单卡到多卡你不需要重新学习一套完全不同的编程模型——put、get、atomic、barrier这些概念在DUSHMEM里都能找到直观的对应。

相关新闻

MoE 推理部署实战:同样的 6GB 显存,你选速度还是能力?

MoE 推理部署实战:同样的 6GB 显存,你选速度还是能力?

副标题: 三个模型、两组对比、一个三元 trade-off——MoE 在 6GB 家用卡上的真实表现 一、引子:纸上得来终觉浅 上一篇《大模型架构演进全景》从理论上梳理了 MoE 的设计思想:总参数大、激活参数小、每个 token 只走部分专家,用稀…

2026/7/9 1:14:42阅读更多 →
推荐太原多色美缝胶

推荐太原多色美缝胶

在家装翻新或新房装修中,美缝胶的选择往往是影响整体质感的关键细节。面对市场上琳琅满目的品牌和色彩,用户容易陷入“如何选色”、“哪种更耐黄变”、“哪里找靠谱施工团队”等困惑。针对太原本地用户,我们梳理了多色美缝胶的选购要点&#…

2026/7/9 1:14:42阅读更多 →
工业声音异常检测:Log-Mel Spectrogram 与 MFCC 特征选型指南

工业声音异常检测:Log-Mel Spectrogram 与 MFCC 特征选型指南

工业声音异常检测:Log-Mel Spectrogram 与 MFCC 特征选型指南 一、 核心结论 针对基于深度学习的工业声音异常检测任务(如 CNN、CRNN、频谱输入型 Transformer 等表示学习模型),Log-Mel Spectrogram(对数梅尔频谱&am…

2026/7/9 1:14:42阅读更多 →
硬核拆解ZLinear采集卡ADC数据包:从内存结构体到上位机波形解析的完整链路

硬核拆解ZLinear采集卡ADC数据包:从内存结构体到上位机波形解析的完整链路

zlinear开源电子 前言 大家好,我是ZLinear的硬件工程师。 在之前的系列博文中,我们从AD7606的硬件隔离架构聊到了16位ADC榨出24位精度的过采样算法,很多读者直呼过瘾。但也有朋友在评论区提出了一个极其锐利的问题: "张工…

2026/7/9 2:04:45阅读更多 →
【大数据课程设计/毕业设计】基于大数据建模的淘宝电子产品营销分析系统的设计与实现 基于数据可视化的淘宝电子产品电商运营辅助系统【附源码、数据库、万字文档】

【大数据课程设计/毕业设计】基于大数据建模的淘宝电子产品营销分析系统的设计与实现 基于数据可视化的淘宝电子产品电商运营辅助系统【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/9 2:04:45阅读更多 →
大数据毕设项目:基于多维统计的淘宝电子产品市场竞争力分析系统的设计与实现 基于 Django 架构的淘宝电商数码数据监测系统 (源码+文档,讲解、调试运行,定制等)

大数据毕设项目:基于多维统计的淘宝电子产品市场竞争力分析系统的设计与实现 基于 Django 架构的淘宝电商数码数据监测系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/9 2:04:45阅读更多 →
Azure Local 多机架(Rack Aware Cluster)部署(系列篇之二)

Azure Local 多机架(Rack Aware Cluster)部署(系列篇之二)

文档定位:基于 azloc-2606 官方部署文档(deploy-via-portal、deployment-azure-resource-manager-template、deploy/rack-aware-cluster-post-deployment、network-atc-overview、add-server、repair-server、host-network-requirements)。 适…

2026/7/9 2:04:44阅读更多 →
ISC DHCP完全指南:网络自动配置的终极解决方案

ISC DHCP完全指南:网络自动配置的终极解决方案

ISC DHCP完全指南:网络自动配置的终极解决方案 【免费下载链接】dhcp ISC DHCP is a collection of software that implements all aspects of the DHCP (Dynamic Host Configuration Protocol). 项目地址: https://gitcode.com/openeuler/dhcp 前往项目官网…

2026/7/9 2:04:44阅读更多 →
【Springboot毕设全套源码+文档】基于SpringBoot的新能源二手汽车销售平台的设计与实现(丰富项目+远程调试+讲解+定制)

【Springboot毕设全套源码+文档】基于SpringBoot的新能源二手汽车销售平台的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/9 1:59:44阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/8 5:12:14阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/8 7:00:12阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/8 2:26:06阅读更多 →
Three.js 着色器光效教程

Three.js 着色器光效教程

着色器光效 Shader Light ▶ 在线运行案例 案例合集: 三维可视化功能案例(threehub.cn)开源仓库github地址: https://github.com/z2586300277/three-cesium-examples400个案例代码: 网盘链接 你将学到什么 ShaderMaterial 自…

2026/7/9 0:04:37阅读更多 →
如何5分钟掌握CS2智能库存管理:开源工具CASEMOVE终极指南

如何5分钟掌握CS2智能库存管理:开源工具CASEMOVE终极指南

如何5分钟掌握CS2智能库存管理:开源工具CASEMOVE终极指南 【免费下载链接】casemove A dedicated desktop app that enables you to move items in and out of storage units in CS2. 项目地址: https://gitcode.com/gh_mirrors/ca/casemove 还在为CS2存储单…

2026/7/9 0:04:37阅读更多 →
GBase 8a vs MySQL 8.0:ALTER TABLE语法与限制的5点关键差异对比

GBase 8a vs MySQL 8.0:ALTER TABLE语法与限制的5点关键差异对比

GBase 8a与MySQL 8.0:ALTER TABLE语法差异深度解析与实战指南1. 两种数据库的ALTER TABLE能力全景对比在数据库架构设计和运维过程中,表结构变更(DDL操作)是不可避免的需求。GBase 8a作为国产分析型数据库代表,与开源M…

2026/7/9 0:04:37阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/8 6:59:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/8 13:42:39阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/8 13:42:39阅读更多 →