You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MPI_Scatter≥5核运行触发write error Bad address(3)错误排查

问题根因

直接原因是内存不足导致堆分配失败,且代码未做malloc返回值校验,具体推导:

  • 你定义的2400*2400单精度浮点矩阵,单矩阵占用内存为2400 * 2400 * 4 = 23040000字节,约22MiB。当前代码里所有MPI进程(无论rank值)都分配了A、B、C三个全尺寸矩阵,再加每个进程的局部分片矩阵Asc,单进程固定内存占用约70MiB。
  • 核心数≤4时,所有进程总内存占用约280MiB,树莓派剩余可用内存可满足分配需求,所有malloc调用正常返回,程序可以跑完Scatter流程。
  • 核心数≥5时,总进程内存占用超过350MiB。树莓派本身系统服务、GPU划分显存会占用一部分内存,剩余可用内存不足以支撑所有进程的全量矩阵分配。注意你的内存分配顺序是Asc -> B -> C -> A,A是最后一个分配的全尺寸矩阵,内存不足时A的malloc调用直接返回NULL,但代码没有做任何返回值检查,直接把这个非法地址传给了MPI_Scatter。
  • 前面的MPI_Bcast操作使用的是提前分配成功的B矩阵,所以可以正常执行,能打印出"Before Scatter"日志;到MPI_Scatter执行时,rank0需要从A指向的内存读取待分发的数据,访问非法地址就触发了tcp传输层的Bad address报错,和你观察到的崩溃位置完全一致。
修复方案
  • 砍掉非必要内存分配:只有rank0需要存储完整的源矩阵A,非根进程不需要给A分配全尺寸内存,调用MPI_Scatter时非根进程直接传NULL作为sendbuf参数即可(MPI标准明确规定非根进程的sendbuf参数会被忽略,不会被访问)。单非根进程可直接省出22MiB内存,大幅降低整体内存压力。如果后续计算逻辑中非根进程不需要存储完整的C矩阵,同理按需分配即可,不要所有进程都预分配全尺寸数组。
  • 所有malloc调用必须加返回值校验,分配失败时打印错误信息直接退出,避免野指针导致的无意义排查。
  • 如果后续需要使用不能整除2400的进程数运行,需要把MPI_Scatter替换为MPI_Scatterv,手动指定每个进程接收的数据长度和偏移,避免整数除法导致的数据遗漏或越界访问。
快速验证方法

临时把n_rows、n_cols改成1200,此时单全尺寸矩阵仅占约5.5MiB,单进程内存占用不到20MiB,哪怕跑8个核心总内存占用也不到160MiB,如果修改后核心数≥5也能正常运行,即可完全确认是内存不足导致的问题。

内容的提问来源于stack exchange,提问作者Enzo Basile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:33:41