运行osu_alltoall/osu_alltoallv/osu_alltoallw/osu_ialltoall/osu_ialltoallv/osu_ialltoallw时出现内存耗尽问题
现象描述
在满核(核数576、内存约500GB)下运行osu_alltoall/osu_alltoallv/osu_alltoallw/osu_ialltoall/osu_ialltoallv/osu_ialltoallw,当使用默认的max_message_size(1MB)时,会出现内存耗尽问题。
可能原因
通过实测及理论分析,运行osu_alltoall/osu_alltoallv/osu_alltoallw/osu_ialltoall/osu_ialltoallv/osu_ialltoallw时,会申请较多的内存,内存占用主要包含以下2个方面:
- 每个进程需要申请sendbuf和recvbuf两块内存,每个大小为:
bufsize = options.max_message_size * numprocs(需要按PAGESIZE对齐)
如果指定-c参数,则需要额外申请expected_buffer和temp_buffer两块内存,大小和sendbuf、recvbuf的大小相等。
- UM通信所需要的内存size_um。
每个节点需要的内存大小:
- 不指定-c参数:
- 指定-c参数:
osu_alltoall默认的max_message_size为1MB,按单节点2p、进程数575计算,最少需要650GB,远远大于单节点16张32GB满插内存。
在上述计算中:
- UM通信所需要的内存size_um约为4GB。
- 单节点满插实际可用内存为471GB。
恢复步骤
根据上述公式合理设置max_message_size。例如按最大16节点满核(每个节点的进程数576、内存500GB)计算,在指定-c参数时,建议设置"-m 16384"将max_message_size设置为16KB。
除了通过上述解决方案规避之外,还可以修改用例/应用源码,在调用MPI_Alltoall/MPI_Alltoallv/MPI_Alltoallw/MPI_Ialltoall/MPI_Ialltoallv/MPI_Ialltoallw接口时,将sbuf修改为MPI_IN_PLACE,以降低这些接口使用的内存规模。