如何使用霍克尼模型参数创建MPI性能模型



我知道参数α和β可以在霍克尼模型中用于表示对等通信中的延迟和带宽,m表示消息大小。例如:

T(m) = α + β · m

我一直在尝试使用这种技术对一些OpenMPI算法进行建模,但无法为MPI_Scatter找到以下算法:

int
ompi_coll_base_scatter_intra_linear_nb(const void *sbuf, int scount,
struct ompi_datatype_t *sdtype,
void *rbuf, int rcount,
struct ompi_datatype_t *rdtype,
int root,
struct ompi_communicator_t *comm,
mca_coll_base_module_t *module,
int max_reqs)
{
int i, rank, size, err, line, nreqs;
ptrdiff_t incr;
char *ptmp;
ompi_request_t **reqs = NULL, **preq;
rank = ompi_comm_rank(comm);
size = ompi_comm_size(comm);
/* If not root, receive data. */
if (rank != root) {
err = MCA_PML_CALL(recv(rbuf, rcount, rdtype, root,
MCA_COLL_BASE_TAG_SCATTER,
comm, MPI_STATUS_IGNORE));
if (MPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
return MPI_SUCCESS;
}
if (max_reqs <= 1) {
max_reqs = 0;
nreqs = size - 1; /* no send for myself */
} else {
/* We use blocking MPI_Send (which does not need a request)
* every max_reqs send operation (which is size/max_reqs at most),
* therefore no need to allocate requests for these sends. */
nreqs = size - (size / max_reqs);
}
reqs = ompi_coll_base_comm_get_reqs(module->base_data, nreqs);
if (NULL == reqs) {
err = OMPI_ERR_OUT_OF_RESOURCE;
line = __LINE__; goto err_hndl;
}
err = ompi_datatype_type_extent(sdtype, &incr);
if (OMPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
incr *= scount;
/* I am the root, loop sending data. */
for (i = 0, ptmp = (char *)sbuf, preq = reqs; i < size; ++i, ptmp += incr) {
/* simple optimization */
if (i == rank) {
if (MPI_IN_PLACE != rbuf) {
err = ompi_datatype_sndrcv(ptmp, scount, sdtype, rbuf, rcount,
rdtype);
}
} else {
if (!max_reqs || (i % max_reqs)) {
err = MCA_PML_CALL(isend(ptmp, scount, sdtype, i,
MCA_COLL_BASE_TAG_SCATTER,
MCA_PML_BASE_SEND_STANDARD,
comm, preq++));
} else {
err = MCA_PML_CALL(send(ptmp, scount, sdtype, i,
MCA_COLL_BASE_TAG_SCATTER,
MCA_PML_BASE_SEND_STANDARD,
comm));
}
}
if (MPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
}
err = ompi_request_wait_all(preq - reqs, reqs, MPI_STATUSES_IGNORE);
if (MPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
return MPI_SUCCESS;
err_hndl:
if (NULL != reqs) {
/* find a real error code */
if (MPI_ERR_IN_STATUS == err) {
for (i = 0; i < nreqs; i++) {
if (MPI_REQUEST_NULL == reqs[i]) continue;
if (MPI_ERR_PENDING == reqs[i]->req_status.MPI_ERROR) continue;
if (reqs[i]->req_status.MPI_ERROR != MPI_SUCCESS) {
err = reqs[i]->req_status.MPI_ERROR;
break;
}
}
}
ompi_coll_base_free_reqs(reqs, nreqs);
}
OPAL_OUTPUT((ompi_coll_base_framework.framework_output,
"%s:%4dtError occurred %d, rank %2d", __FILE__, line, err, rank));
(void)line;  /* silence compiler warning */
return err;
}

到目前为止,我从代码中了解到,模型应该是

T(NP, m) = (NP − 1) · (α + m · β). 

NP是进程的数量(As Scatter使用除根之外的所有进程进行分布(。

这不考虑使用MPI_Isend发送的非阻塞发送。(根据代码片段中的条件(我不确定如何简单地使用霍克尼模型来解释非阻塞和阻塞发送。

任何帮助都将不胜感激,因为我读过的关于这个主题的论文似乎都没有很好地解释这个过程。

首先,源文件提到,此实现可能只适用于少量进程:对于较大的进程,您可能希望执行树状操作。接下来,max_reqs参数控制在阻塞send调用之前执行的isend调用的数量。因此,该算法的运行时间将等于您进行阻塞发送的次数。在一个理想的世界里。在实践中,非阻塞发送仍然需要序列化。

我的最佳猜测是,这种算法可以处理有多个网卡或每个网卡有多个端口的情况。如果您可以一次发送4条消息(物理!(,则此代码设置3个非阻塞&1阻止发送,当阻止发送完成后,您的网络端口就可以接收下一批消息了。

最新更新