MPI_Send的缓冲区大小问题

在迁移MPI程序时遇到“fatal error in MPI: other MPI error”错误,发现是由于发送大文件时缓冲区大小问题引起。通过调整缓冲区大小及使用MPI_Bsend的缓冲模式,解决了64KB的限制问题。但发现静态声明的数组大小限制导致段错误,需使用动态声明。

        最近一直在忙程序的搬家问题,其实说起来不能再简单了:就是把在公司调好的一个MPI程序搬到gz的大系统上去跑,本以为没啥问题的一个步骤实现起来却各种问题,既遇到编译的问题(第一篇博客中提到的)并解决之后,程序的运行也出现了错误。错误信息为“fatal error in MPI: other MPI error”,而且死掉的进程都是发送进程,这让我百思不解。

        然后我怀疑了各种问题尝试了各种方式:首先,使用gdb调试,但问题在于由于需要修改-O3的优化选项才能调试MPI程序,这导致了程序跑的奇慢……发火,等得受不了了;然后,我就只好回归了最原始的输出调试,但我又惊奇的发现,本应该输出的信息没有输出或者没有按顺序输出,实在是混淆视听发火,问了贵鑫才知道是因为缓冲区可能不满,所以利用flush解决了问题(语法为:cout<<"输出的内容"<<……<<flush);在输出信息的帮助下,我逐渐将出错的位置锁定在了用MPI_Send发送大文件的一条语句上,因为我发现,发送其他的信息比如文件名,文件大小等小的信息都可以正常接收,但发送文件时就出错,我怀疑可能是buffer大小的问题。因为文件名等信息的buffer设置为100个字节,而发送的文件比较大,采用循环发送的方式,缓冲区大小设置为1MB,之前在公司上跑,这个设置是没有问题的,而且为了减少通信开销我还想往大了改,比如10MB或者更大,但在大系统上跑就出了问题,在那边的维护人员的帮助下,我调整了发送的缓冲区大小,最后发现<64KB的buffer size都可以正常运行,但>=64KB就会报上面的错误了,可能是MPI的具体实现不同所致。

      所以我开始尝试用MPI发送的缓冲模式代替标准模式,缓冲模式其实就是用用户提供的缓冲区代替系统的缓冲区,按道理来说就不会有大小限制了,大致的步骤就是申请一个大的buffer,然后利用MPI_buffer_attach将buffer交给MPI,调用MPI_Bsend时,MPI_Bsend的发送缓冲区的内容会拷贝到用户提供的buffer里然后马上返回执行下一条命令,然后MPI会在后台从用户的buffer里将内容发送到接收方,但由于我要循环发送,所以继续执行的话,有可能还没有发送完毕,下一条MPI_Bsend就可能把内容拷贝到用户buffer里从而导致第一条信息的丢失,所以在每次执行MPI_Bsend后利用MPI_buffer_detach将用户的缓冲区清空,这个清空是blocking的,即等待内容发送完毕后才能清空,保证了数据的完整性。需要注意的是,尽管MPI_buffer_attach和MPI_buffer_detach的参数要求很相似,但有所不同,前者的第一个参数是缓冲区的首地址,目的是告诉MPI用户提供的buffer在哪里,第二个参数是buffer的大小;后者的第一个参数是首地址的地址,其实是void **类型,第二个参数是buffer大小的地址,目的都是对这两个地址的内容进行改写。(详见附件代码)改好后,我在公司和gz分别作了测试,在公司能够正常运行,在gz发现还是不能突破64KB的上限,只好请管理员调整这个限制,anyway,总算找到了问题的原因。

        还遇到了一个比较弱的问题,也在这里提出来,算是提醒自己吧:之前在调整发送buffer的大小时,我发现调整为10MB就会出现段错误,百思不解还屁颠儿屁颠儿的去问贵鑫,原来是我一直都是静态声明的数组呃……尴尬静态声明数组不能太大,一般不会超过1~2MB,数组再大的话一定要动态声明啊~~~~尴尬


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值