是否可以强制 MPI 在发送时始终阻塞?
Is it possible to force MPI to always block on send?
有没有办法强制 MPI 总是 阻止发送?这在查找分布式算法中的死锁时可能很有用,否则该算法依赖于 buffering MPI might choose to do on send.
例如,以下程序(运行 有 2 个进程)在我的机器上运行没有问题:
// C++
#include <iostream>
#include <thread>
// Boost
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
int main() {
using namespace std::chrono_literals;
mpi::environment env;
mpi::communicator world;
auto me = world.rank();
auto other = 1 - me;
char buffer[10] = {0};
while (true) {
world.send(other, 0, buffer);
world.recv(other, 0, buffer);
std::cout << "Node " << me << " received" << std::endl;
std::this_thread::sleep_for(200ms);
}
}
但是如果我将 缓冲区 的大小更改为 10000 它会无限期地阻塞。
如果您想要阻止行为,请使用 MPI_Ssend。它将阻塞,直到发布匹配的接收,而不缓冲请求。 MPI_Send 提供的缓冲量是(有意)特定于实现的。尝试不同的实现时,您获得的 10000 缓冲区的行为可能会有所不同。
我不知道您是否真的可以调整缓冲配置,我不会尝试,因为它不可移植。相反,我会尝试在某些调试配置中使用 MPI_Ssend 变体,并在需要最佳性能时使用默认的 MPI_Send。
(免责声明:我不熟悉 boost 的实现,但 MPI 是一个标准。另外,我在发布此答案后看到 Gilles 评论...)
对于纯 MPI 代码,您描述的正是 MPI_Ssend()
给您的。但是,在这里,您使用的不是纯 MPI,而是 boost::mpi。不幸的是,根据 boost::mpi's documentation,不支持 MPI_Ssend()
。
也就是说,也许 boost::mpi 提供了另一种方式,但我对此表示怀疑。
例如,您可以考虑调整 eager limit 值 (http://blogs.cisco.com/performance/what-is-an-mpi-eager-limit) to force that send operation to block on any message size. The way to establish the eager limit, depends on the MPI
implementation. On Intel MPI
you can use the I_MPI_EAGER_THRESHOLD
environment variable (see https://software.intel.com/sites/products/documentation/hpc/ics/impi/41/lin/Reference_Manual/Communication_Fabrics_Control.htm)。
有没有办法强制 MPI 总是 阻止发送?这在查找分布式算法中的死锁时可能很有用,否则该算法依赖于 buffering MPI might choose to do on send.
例如,以下程序(运行 有 2 个进程)在我的机器上运行没有问题:
// C++
#include <iostream>
#include <thread>
// Boost
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
int main() {
using namespace std::chrono_literals;
mpi::environment env;
mpi::communicator world;
auto me = world.rank();
auto other = 1 - me;
char buffer[10] = {0};
while (true) {
world.send(other, 0, buffer);
world.recv(other, 0, buffer);
std::cout << "Node " << me << " received" << std::endl;
std::this_thread::sleep_for(200ms);
}
}
但是如果我将 缓冲区 的大小更改为 10000 它会无限期地阻塞。
如果您想要阻止行为,请使用 MPI_Ssend。它将阻塞,直到发布匹配的接收,而不缓冲请求。 MPI_Send 提供的缓冲量是(有意)特定于实现的。尝试不同的实现时,您获得的 10000 缓冲区的行为可能会有所不同。
我不知道您是否真的可以调整缓冲配置,我不会尝试,因为它不可移植。相反,我会尝试在某些调试配置中使用 MPI_Ssend 变体,并在需要最佳性能时使用默认的 MPI_Send。
(免责声明:我不熟悉 boost 的实现,但 MPI 是一个标准。另外,我在发布此答案后看到 Gilles 评论...)
对于纯 MPI 代码,您描述的正是 MPI_Ssend()
给您的。但是,在这里,您使用的不是纯 MPI,而是 boost::mpi。不幸的是,根据 boost::mpi's documentation,不支持 MPI_Ssend()
。
也就是说,也许 boost::mpi 提供了另一种方式,但我对此表示怀疑。
例如,您可以考虑调整 eager limit 值 (http://blogs.cisco.com/performance/what-is-an-mpi-eager-limit) to force that send operation to block on any message size. The way to establish the eager limit, depends on the MPI
implementation. On Intel MPI
you can use the I_MPI_EAGER_THRESHOLD
environment variable (see https://software.intel.com/sites/products/documentation/hpc/ics/impi/41/lin/Reference_Manual/Communication_Fabrics_Control.htm)。