【发布时间】:2018-05-17 15:45:57
【问题描述】:
我阅读了 MPI 标准并找到了一个包含 MPI_Put 和 MPI_Get 操作的部分。但是,我不清楚作为这些功能基础的 RMA 有什么好处。什么时候最好使用这样的函数而不是异步 MPI_Isend、MPI_Irecv?什么是使用 RMA(不在 MPI 上下文中)的一般用途?
【问题讨论】:
我阅读了 MPI 标准并找到了一个包含 MPI_Put 和 MPI_Get 操作的部分。但是,我不清楚作为这些功能基础的 RMA 有什么好处。什么时候最好使用这样的函数而不是异步 MPI_Isend、MPI_Irecv?什么是使用 RMA(不在 MPI 上下文中)的一般用途?
【问题讨论】:
单面通信的最大好处是能够在节点之间推送或获取数据,而无需发送/接收开销。
想象一个有 2 个节点的场景。您想将数据从节点 1 推送到节点 2。
当节点 1 使用 MPI_ISend 或 MPI_Send 向节点 2 发送数据时,节点 2 仍必须使用 MPI_Irecv 正式接收该数据。节点 2 将等待接收,匹配 MPI 标记,然后允许您继续。这在理论上类似于套接字,因为双方必须协调。即使使用异步版本MPI_I*,仍然存在协调。
使用MPI_Put,您从节点 1 推送数据,节点 2 将拥有它。涉及同步步骤,但关键是节点 2 将拥有它,不需要正式接受。组中的所有节点都可以访问其他节点附加的内存缓冲区。
我的一位同事有一个很好的类比。 MPI_Send 和MPI_Recv 就像邮件递送,收件人必须签收包裹。他们可以无限期地在门口等候 (MPI_Send) 或留个便条让您回电 (MPI_ISend)。
MPI_Put 就像亚马逊送货员走进你的房子并把杂货收起来一样。 MPI_Get 就像你走进一家打烊的杂货店,随便拿你需要的东西。
与此示例类似,MPI_Put 和 MPI_Get 依赖于信任和良好的设计。仅当共享内存和单向数据移动有效时才应使用它们。
好概述:https://www.cc.gatech.edu/~echow/ipcc/hpc-course/19_rma.pdf
【讨论】:
使用 RMA 编写某些应用程序更容易或更自然。 例如,考虑一个 2D 模拟应用程序,其中每个进程都拥有网格的某些部分,但需要来自其他进程的数据才能计算其迭代。使用消息传递原语需要每个进程匹配发送/接收对,并且每个接收者都需要理解每条消息的含义(请在此处写下此数据)。 程序员必须小心避免使用协调发送和接收或通常称为“异步”I中间操作的死锁。 使用 RMA 原语不需要目标消息理解请求,因为它的含义是隐含的(请给我或写这个数据)。
但是,将MPI_Put 和MPI_Get 操作视为真正片面的操作是不正确的。 MPI 设计用于在不同的硬件上工作。某些网络(例如 infiniband)支持真正的 DRMA,因为它们不需要目标进程的参与(正如我读到的 here,情况并非如此)。其他网络不支持 RDMA,而 RMA 标准的设计是为了在不违背本规范的情况下实现高效的 RMA 原语(相对于硬件功能)。
正如Using advanced MPI 一书中所解释的,MPI_Put 不仅仅是一个不需要recv 的发送,而是类似于MPI_Isend,需要一个调用,例如MPI_Wait 或MPI_Test即使发布了相应的MPI_Recv 变体,也能取得进展。
类似地,MPI RMA 操作需要同步操作,例如MPI_Win_fence,这是最基本的可以取得进展的操作。 MPI 标准只说这些操作最迟应该在调用一个这样的操作时完成,这意味着它可以在之前完成。该行为取决于 MPI 实现,而 RMA 操作实际上可以使用消息传递来实现。
【讨论】: