[英]MPI_Send and MPI_Recv overhead
因此,我試圖找出使用C代碼中的MPI在處理器之間發送和接收信息的通信開銷。
我需要在發送和接收中都傳遞一個緩沖區,但是我要做的只是計時兩個處理器之間進行通信所花費的時間。
這是我的整個代碼:
main(int argc, char** argv){
int n;
int rank;
int time;
int i;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(rank == 0){
n = atoi(argv[1]);
printf("Size of data set = %d\n", n);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
for(i = 0; i < n; i++){
if(rank == 0){
MPI_Send(&n, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
}
else{
MPI_Recv(&n, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
}
}
MPI_Barrier(MPI_COMM_WORLD);
time = clock();
printf("Time: %d\n", time);
MPI_Finalize();
}
我做了一些測試,發現當我取出for循環時,它可以按照我想要的方式工作。 那么,導致無限循環或段錯誤的for循環又有什么問題呢?
有兩個問題:
1)在代碼中沒有檢查以確保它收到了“數據集的大小”。 如果您在沒有有效命令行選項的情況下啟動代碼,它將導致段錯誤或取決於您的系統,以無法預測的方式繼續進行。
2)發送和接收中的標簽不匹配。 標簽必須匹配才能成功通信。 沒有匹配的標簽,Recv將永遠等待直到找到匹配的發送。 發送等待直到找到匹配的接收方。
將MPI_COMM_WORLD旁邊的接收中的1更改為0,代碼將正常運行。
下面是一個完整的程序,它可以滿足您的要求。 存在一些會阻止原始版本工作的問題:
n
添加了默認值。 祝好運!
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <mpi.h>
#define TAG_NUMBER 777 // just something
#define DEFAULT_N 10000000 // takes ~3 seconds on my laptop
int main(int argc, char **argv)
{
int i,n,rank,size,message=0;
clock_t start = clock();
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// This test assumes two processes in MPI_COMM_WORLD
// ---------------------------------------------------------------------------
if (size != 2) {
if (rank == 0) { // only rank 0 prints
printf("Please run with exactly 2 processes.\n");
}
MPI_Finalize();
return 1;
}
// Collect from the command line the number of messages to send, default to
// DEFAULT_N.
// ---------------------------------------------------------------------------
if (rank == 0) {
if (argc > 1) {
n = atoi(argv[1]);
}
else {
n = DEFAULT_N;
}
printf("Number of messages to send = %d\n", n);
}
// Make sure everyone has the same n.
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
// ---------------------------------------------------------------------------
// Here we have ranks 1 and 2 exchange n messages via MPI_Send and MPI_Recv.
// ---------------------------------------------------------------------------
for (i=0; i<n; i++) {
if (rank == 0) {
MPI_Send(&message, 1, MPI_INT, 1, TAG_NUMBER, MPI_COMM_WORLD);
}
else{
MPI_Recv(&message, 1, MPI_INT, 0, TAG_NUMBER, MPI_COMM_WORLD, &status);
}
}
MPI_Barrier(MPI_COMM_WORLD); // not really necessary
printf("rank %d: time = %f seconds\n", rank,
(double)(clock() - start)/CLOCKS_PER_SEC);
MPI_Finalize();
return 0;
}
我相信,除非您恰好使用了兩個MPI進程,否則代碼會掛起。
您是否嘗試過流基准測試 ?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.