Communication cost of MPI send and receive
我是 MPI 新手,想测量两个节点之间 MPI_Send 和 MPI_Recv 的通信成本。为此,我编写了以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /*============================================================== * 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("\ %s total elapsed time = %ld (usec)\ ", 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]\ \ ", 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("\ Executing %s: numElements=%d \ ", 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()\ ", 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() */ |
我重复发送和接收
如果您想要描述的详细程度,您可能必须深入了解 MPI 库本身的实现。您正在测量的是通信对您的应用程序的影响。但是,取决于您的基础架构,通信中涉及的内容可能更多。一些网络可以在不涉及应用程序的情况下取得进展,一些 MPI 库也可以使用线程来异步处理消息。
你如何衡量这些东西将取决于你的系统和上述限制。如果您只关心您的应用程序在通信调用中花费了多少时间,那么您或多或少已经完成了这一点。您可以使用其他跟踪工具来完成类似的事情(HPCtoolkit 是我过去使用过的一种)。
如果您想获得有关幕后情况的更详细信息,您将不得不深入了解您的实现并开始在内部进行检测(假设您使用的是开源实现,例如MPICH 或开放 MPI)。这是一个涉及更多的过程,并且机制将从一种实现更改为另一种实现。