MPI发送和接收的通信成本

Communication cost of MPI send and receive

本文关键字:通信 MPI      更新时间:2023-10-16

我是MPI的新手,想测量MPI_Send和MPI_Recv在两个节点之间的通信成本。我为此写了以下代码:

/*==============================================================
* print_elapsed (prints timing statistics)
*==============================================================*/
void print_elapsed(const char* desc, struct timeval* start, struct timeval* end, int numiterations) {
struct timeval elapsed;
/* calculate elapsed time */
if(start->tv_usec > end->tv_usec) {
end->tv_usec += 1000000;
end->tv_sec--;
}
elapsed.tv_usec = end->tv_usec - start->tv_usec;
elapsed.tv_sec  = end->tv_sec  - start->tv_sec;
printf("n%s total elapsed time = %ld (usec)n",
desc, (elapsed.tv_sec*1000000 + elapsed.tv_usec)/numiterations );
}

int main(int argc, char **argv) {
int nprocs, nElements; /* command line args */
int my_id;
long double* buffer, *rec_buffer;         
/* gettimeofday stuff */
struct timeval start, end;         /* gettimeofday stuff */
struct timezone tzp;
MPI_Status status;              /* Status variable for MPI operations */
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_id); /* Getting the ID for this process */
/*---------------------------------------------------------
*  Read Command Line
*  - check usage and parse args
*---------------------------------------------------------*/
if(argc < 2) {
if(my_id == 0)
printf("Usage: %s [nElements]nn", argv[0]);
MPI_Finalize();
exit(1);
}
nElements = atoi(argv[1]);
int numiterations = 64;
MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* Get number of processors */
if(my_id == 0)
printf("nExecuting %s: numElements=%d n",
argv[0], nElements);

buffer = (long double *) malloc(sizeof(long double)*nElements);
rec_buffer = (long double *) malloc(sizeof(long double)*nElements);
if(buffer == NULL) {
printf("Processor %d - unable to malloc()n", my_id);
MPI_Finalize();
exit(1);
}

MPI_Barrier(MPI_COMM_WORLD);
if(my_id == 1)
gettimeofday(&start, &tzp);

for(int i = 0 ; i < numiterations ; ++i)
{
if(my_id == 0)
MPI_Send(buffer, nElements, MPI_LONG, 1, 0, MPI_COMM_WORLD);
if(my_id == 1)
MPI_Recv(rec_buffer, nElements, MPI_LONG, 0, 0, MPI_COMM_WORLD, &status);
}

if(my_id == 1) {
gettimeofday(&end,&tzp);
}
MPI_Barrier(MPI_COMM_WORLD);
if(my_id == 1) {
print_elapsed("Summation", &start, &end, numiterations);
}
free(buffer);
MPI_Finalize();
return 0;
} /* main() */

我重复numiteration次发送和接收,但我没有关于初始化成本和实际通信时间的信息。我想知道是否有更好的方法或工具来更详细地衡量沟通成本。

如果您想要描述的详细级别,您可能必须深入到MPI库本身的实现中。您衡量的是通信对应用程序的影响。然而,根据您的基础设施,可能会有更多的通信参与。一些网络可以在不涉及应用程序的情况下进行处理,而一些MPI库也可以使用线程异步处理消息。

如何衡量这些东西将取决于您的系统和上述限制。如果你关心的只是你的应用程序在阻止通信调用上花费了多少时间,那么你或多或少已经完成了这一点。您可以使用其他跟踪工具来完成类似的事情(HPCtoolkit是我过去使用过的工具)。

如果你想获得更多关于幕后情况的详细信息,你必须深入了解你的实现并开始内部检测(假设你使用的是开源实现,如MPICH或open MPI)。这是一个更为复杂的过程,机制将从一种实施方式变为另一种实施。