是否可以强制 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)。