我正在开发一个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
时都不会产生延迟?
答案 0 :(得分:2)
通过std::list
元素逐步步进和发送确实会导致显着的通信开销。
MPI规范/库旨在与语言无关。这就是它使用语言不可知MPI datatypes的原因。结果是它只能从连续缓冲区(这是大多数语言提供的功能)发送,而不是从列表等更复杂的数据结构发送。
为了避免逐个发送的通信开销,有两种选择:
将所有列表元素复制到std::vector
并发送向量。然而,这会创建一个内存溢出并使发送完全顺序(并且在此期间一些MPI节点可能是谜语)。
或遍历您的列表,构建较小的向量/缓冲区并发送这些较小的块(最终将它们分派到多个目标节点?)。这种方法的好处是可以通过 流水线效果 更好地利用i/o latency and parallelism。但是,您需要进行一些实验以找到中间块的optimal size。