3

听说 PSM 是一个支持标签匹配的库。什么是标签匹配接口?为什么标签匹配对 MPI 环境中的性能很重要?

4

1 回答 1

4

MPI 标记匹配的简短介绍:https ://www.hpcwire.com/2006/08/18/a_critique_of_rdma-1/ “匹配”部分

MPI 是一个具有大匹配空间的双向接口:根据 Sender、Tag 和 Context 等几个标准,MPI Recv 与 MPI Send 相关联,前两个可能被忽略(通配符)。匹配不一定按顺序进行,更糟糕的是,可以在匹配的 MPI Recv 之前发布 MPI Send ... MPI 需要 64 位匹配信息,而 MX、Portals 和 QsNet 提供了这样的匹配能力。

InfiniBand Verbs 和其他基于 RDMA 的 API 根本不支持匹配

因此,听起来 PSM 是一种包含对 Infiniband 式网络适配器的快速匹配的方法(第一个版本具有软件匹配,但有可能将部分匹配移动到硬件)。

我找不到 PSM 的公共文档(用户指南http://storusint.com/pdf/qlogic/InfiniPath%20User%20Guide%202_0.pdf中没有详细信息)。但是有图书馆的来源:https ://github.com/01org/psm

PSM2 演示文稿中列出了一些详细信息https://www.openfabrics.org/images/eventpresos/2016presentations/304PSM2Features.pdf

什么是 PSM?匹配队列 (MQ) 组件

  • • 使用标签匹配在语义上匹配 MPI 的需求
  • • 提供通话进度保证
  • • MQ 完成语义(标准与同步)

PSM API

  • • 具有64 位标签的全局标签匹配 API
  • • 每个作业最多可扩展至 64K 进程
  • • MQ API 提供端点之间的点对点消息传递
  • • 例如 psm_mq_send、psm_mq_irecv
  • • 没有“recvfrom”功能——某些应用程序需要

因此,有 64 位标签。每条消息都有一个标签,匹配队列有标签(在一些标签匹配实现中也有标签掩码)。根据来源 psm_mq_internal.h:mq_req_match() https ://github.com/01org/psm/blob/67c0807c74e9d445900d5541358f0f575f22a630/psm_mq_internal.h#L381 ,PSM中有掩码:

typedef struct psm_mq_req {
...
    /* Tag matching vars */
    uint64_t    tag;
    uint64_t    tagsel;     /* used for receives */
...
} psm_mq_req_t;

mq_req_match(struct mqsq *q, uint64_t tag, int remove)
)
{
    psm_mq_req_t *curp;
    psm_mq_req_t cur;

    for (curp = &q->first; (cur = *curp) != NULL; curp = &cur->next) {
      if (!((tag ^ cur->tag) & cur->tagsel)) { /* match! */
        if (remove) {
          if ((*curp = cur->next) == NULL) /* fix tail */
            q->lastp = curp;
          cur->next = NULL;
        }
        return cur;
      }
    }

因此,匹配是当传入的标签与tag接收异或,发布到 MQ,结果与tagsel接收。如果在这些操作之后只有零位,则找到匹配项,否则处理下一次接收。

来自函数的评论,psm_mq.hhttps ://github.com/01org/psm/blob/4abbc60ab02c51efee91575605b3430059f71ab8/psm_mq.h#L206psm_mq_irecv()

/* Post a receive to a Matched Queue with tag selection criteria
 *
 * Function to receive a non-blocking MQ message by providing a preposted
 * buffer. For every MQ message received on a particular MQ, the tag and @c
 * tagsel parameters are used against the incoming message's send tag as
 * described in tagmatch.
 *
 * [in] mq Matched Queue Handle
 * [in] rtag Receive tag
 * [in] rtagsel Receive tag selector
 * [in] flags Receive flags (None currently supported)
 * [in] buf Receive buffer 
 * [in] len Receive buffer length
 * [in] context User context pointer, available in psm_mq_status_t
 *                    upon completion
 * [out] req PSM MQ Request handle created by the preposted receive, to
 *                 be used for explicitly controlling message receive
 *                 completion.
 *
 * [post] The supplied receive buffer is given to MQ to match against incoming
 *       messages unless it is cancelled via psm_mq_cancel @e before any
 *       match occurs.
 *
 * The following error code is returned.  Other errors are handled by the PSM
 * error handler (psm_error_register_handler).
 *
 * [retval] PSM_OK The receive buffer has successfully been posted to the MQ.
 */
psm_error_t
psm_mq_irecv(psm_mq_t mq, uint64_t rtag, uint64_t rtagsel, uint32_t flags,
         void *buf, uint32_t len, void *context, psm_mq_req_t *req);

将数据编码到标签中的示例:

 *     uint64_t tag = ( ((context_id & 0xffff) << 48) |
 *                      ((my_rank & 0xffff) << 32)    |
 *                      ((send_tag & 0xffffffff)) );

使用tagsel掩码,我们可以对“匹配所有内容”、“匹配具有某些字节或位等于值的标签以及其他任何内容”、“完全匹配”的标签进行编码。

还有更新的 PSM2 API,也是开源的 - https://github.com/01org/opa-psm2,程序员指南发布在http://www.intel.com/content/dam/support/us/en/documents/网络/omni-adptr/sb/Intel_PSM2_PG_H76473_v1_0.pdf

PSM2中标签较长,定义了匹配规则(stag为“Message Send Tag”——message中发送的标签值,rtag为receive request的标签): https ://www.openfabrics.org/images/eventpresos /2016presentations/304PSM2Features.pdf#page=7

标签匹配改进

  • • 将标签大小增加到 96 位
  • • 从根本上说((stag ^ rtag) & rtagsel) == 0
  • • 支持通配符,例如MPI_ANY_SOURCEMPI_ANY_TAG使用零位rtagsel
  • • 允许几乎无限的可扩展性
  • • 每个作业多达 6400 万个进程

PSM2 标签匹配

#define PSM_MQ_TAG_ELEMENTS 3 
typedef 
struct
 psm2_mq_tag { 
    union { 
        uint32_t tag[PSM_MQ_TAG_ELEMENTS] __attribute__((aligned(16))); 
        struct { 
            uint32_t tag0; 
            uint32_t tag1; 
            uint32_t tag2; 
        }; 
    }; 
} psm2_mq_tag_t;
  • • 应用程序填充“tag”数组或“tag0/tag1/tag2”并传递给 PSM
  • • 标签和标签掩码都使用相同的 96 位标签类型

实际上在psm2_mq_req结构中匹配变量附近有源对等地址:https ://github.com/01org/opa-psm2/blob/master/psm_mq_internal.h#L180

   /* Tag matching vars */
   psm2_epaddr_t peer;
   psm2_mq_tag_t tag;
   psm2_mq_tag_t tagsel;    /* used for receives */

和软件列表扫描匹配,从https://github.com/01org/opa-psm2/blob/85c07c656198204c4056e1984779fde98b00ba39/psm_mq_recv.c#L188mq_list_scan()调用:mq_req_match()

psm2_mq_req_t
mq_list_scan(struct mqq *q, psm2_epaddr_t src, psm2_mq_tag_t *tag, int which, uint64_t *time_threshold)
{
    psm2_mq_req_t *curp, cur;

    for (curp = &q->first;
         ((cur = *curp) != NULL) && (cur->timestamp < *time_threshold);
         curp = &cur->next[which]) {
        if ((cur->peer == PSM2_MQ_ANY_ADDR || src == cur->peer) &&
            !((tag->tag[0] ^ cur->tag.tag[0]) & cur->tagsel.tag[0]) &&
            !((tag->tag[1] ^ cur->tag.tag[1]) & cur->tagsel.tag[1]) &&
            !((tag->tag[2] ^ cur->tag.tag[2]) & cur->tagsel.tag[2])) {
            *time_threshold = cur->timestamp;
            return cur;
        }
    }
    return NULL;
}
于 2016-07-10T15:05:52.827 回答