MPI_Recv / MPI_Send开销

时间:2016-01-17 12:55:39

标签: c++ mpi

我正在开发一个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<int>),我不能使用版本A但必须求助于版本B或将列表的内容复制到连续容器(例如std::vector<int>)首先使用版本A.因为我想避免额外的副本,我想知道MPI中是否有任何选项/其他功能允许有效使用版本B(或者至少类似的,类似循环的构造),每次调用MPI_Send时都不会产生延迟?

1 个答案:

答案 0 :(得分:2)

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

MPI规范/库旨在与语言无关。这就是它使用语言不可知MPI datatypes的原因。结果是它只能从连续缓冲区(这是大多数语言提供的功能)发送,而不是从列表等更复杂的数据结构发送。

为了避免逐个发送的通信开销,有两种选择:

  • 将所有列表元素复制到std::vector并发送向量。然而,这会创建一个内存溢出并使发送完全顺序(并且在此期间一些MPI节点可能是谜语)。

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