gpt4 book ai didi

c++ - MPI - Bsend 用法

转载 作者:搜寻专家 更新时间:2023-10-30 23:52:59 25 4
gpt4 key购买 nike

当我想在异步发送之后恰好释放资源时,MPI_Bsend 好吗?这将:

MPI_Bsend(&array[0],...)
delete[] array;

阻止我删除我想发送的内存(问题是,当适当的 recv 开启时,数组可能已经被删除)?

更新:

void RectMPIAngleFiller::setglobalFillerbounds1() {

int_t SIZE = getSolver()->getNumInterpolators() * procnums;
int_t gridnums = getSolver()->getNumGrids();
if (layer == 1) {
if (local_rank == 0) {
MPI_Isend(&rank_size, 1, MPI_INT, 0, gridnum, MPI_COMM_WORLD);
}
} else if (layer == 0) {
int_t fillernumber = getSolver()->getNumInterpolators();
int_t local_fillernum = fillernum % fillernumber;
if (local_rank == 0 && local_fillernum == 0) {
int_t * incomeSizes = new incomeSizes[gridnums];
incomeSizes[gridnum] = getSolver()->getNumInterpolators();

for ( int_t i = 0; i < gridnums; i++) {
if (i != gridnum)
MPI_Irecv(&incomeSizes[i], 1, MPI_INT, MPI_ANY_SOURCE, i, MPI_COMM_WORLD, &request);
}

}
}
}

例如,我现在有这样一个函数(现在可能不正确),它从许多进程中收集大小,这些进程可能相同但运行在不同的类实例上,这就是为什么一切都与发送有关。

此函数在每个实例的外循环中运行,我希望它在整个循环之后完成。

现在它只接收大小,我不想要这个并且想删除一些内部数组并根据同一函数中接收到的大小调整它们的大小。如果我有非常大的数组,Isend 中的内部缓冲区太小而无法存储所有信息。

最佳答案

缓冲发送和非阻塞发送之间的区别在 MPI 中有点微妙。实际上,它们都可以用来避免死锁,因为这两个例程都在消息传递之前将控制权返回给用户(或者更确切地说,它们将始终返回给用户,但此时无法保证消息已传递)。在实践中,这意味着两者都不需要等待匹配的接收被发布,这有助于避免死锁。

但是,MPI_Bsend 保证数据已被复制到缓冲区。用户需要确保他们通过 MPI_Buffer_attach 提供了足够的内存,以便缓冲所有未完成的消息。这是一条消息还是更多消息取决于您的程序的逻辑。

MPI_Isend 不保证消息已被复制到缓冲区。心智模型是发送已被推迟到以后 - 您已要求 MPI 在将来某个时间方便时发送消息。您必须等待相关请求以确保 MPI_Send 已完成。

  • 当 MPI_Bsend 返回时,释放发送缓冲区是安全的,因为它保证已复制到用户提供的缓冲区。
  • 当 MPI_Isend 返回时,释放发送缓冲区是不安全的。

  • 当 MPI_Wait(&request, &status) 返回时,可以安全地释放发送缓冲区。这是因为或者数据已经被复制到缓冲区(系统缓冲区,不是您通过 Buffer_attach 提供的缓冲区)因为它已安全地传送到匹配的 MPI_Recv。

MPI 可以自由选择是否缓冲 MPI_Send。在实践中,小消息会被缓冲,而大消息则不会。

虽然 MPI_Ibsend 的存在是为了完整性,但我想不出真正的用例。原则上,它可以在消息被复制到用户提供的缓冲区之前返回,因此在等待之前您不能释放发送缓冲区。那么您可以将用户代码与拷贝重叠吗?在实践中似乎有点毫无意义。

关于c++ - MPI - Bsend 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42606441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com