【问题标题】:MPI_Recv/MPI_Send overheadMPI_Recv/MPI_Send 开销
【发布时间】:2016-04-22 16:03:38
【问题描述】:

我正在开发一个 C++ 应用程序,我使用 MPI C 绑定通过网络发送和接收数据。我明白发送

const int VECTOR_SIZE = 1e6;
std::vector<int> vector(VECTOR_SIZE, 0.0);

通过

// Version A
MPI_Send(const_cast<int *>(vector.data()), vector.size(), MPI_INT, 1, 0, MPI_COMM_WORLD);

比

更有效率
// Version B
for (const auto &element : vector)
    MPI_Send(const_cast<int *>(&element), 1, MPI_INT, 1, 0, MPI_COMM_WORLD);

由于MPI_Send 引入的延迟。但是,如果我想发送内存中不连续的数据结构(例如 std::list&lt;int&gt;),我不能使用版本 A,但必须求助于版本 B 或将列表的内容复制到连续容器(如 @987654326 @,例如)首先使用版本 A。由于我想避免额外的副本,我想知道 MPI 中是否有任何选项/其他函数可以有效使用版本 B(或至少类似的循环- like 构造)而不会在每次调用 MPI_Send 时产生延迟?

【问题讨论】:

  • 你可以看看 Boost MPI,因为它支持 STL 容器。

标签: c++ mpi


【解决方案1】:

通过std::list 元素逐个发送和发送确实会导致显着的通信开销。

MPI 规范/库设计为独立于语言。这就是为什么它使用与语言无关的MPI datatypes。结果是它只能从连续的缓冲区(这是大多数语言提供的功能)发送,而不能从更复杂的数据结构(如列表)发送。

为了避免一一发送的通信开销,有两种方案:

  • 将所有列表元素复制到std::vector 并发送向量。然而,这会造成内存溢出并使发送完全按顺序发送(并且在此期间某些 MPI 节点可能处于中间状态)。

  • 或遍历您的列表,构建更小的向量/缓冲区并发送这些更小的块(最终将它们分派到多个目标节点?)。这种方法的好处是可以通过流水线效果更好地利用i/o latency and parallelism。但是,您必须进行一些试验才能找到中间块的optimal size。

【讨论】:

    猜你喜欢
    • 2011-01-24
    • 2011-11-11
    • 2014-04-17
    • 1970-01-01
    • 2016-09-09
    • 2017-10-25
    • 2018-03-05
    • 2018-05-29
    • 2015-05-14
    相关资源
    最近更新 更多