mpi连接性能测试

来源:互联网 发布:苹果编程语言 编辑:程序博客网 时间:2024/06/06 01:29
  1. #include <stdlib.h>    
  2. #include <stdio.h>    
  3. #include <memory.h>    
  4. #include <math.h>    
  5. #include <unistd.h>    
  6. #include <mpi.h>    
  7. #include <assert.h>    
  8. #include <sys/time.h>    
  9. #define SEND 1    
  10. #define RECV 2    
  11. #define LOOP_LAT 10000    
  12. #define SKIP_LAT 100    
  13. #define LOOP_BW  25    
  14. #define MYBUFSIZE (4*1024*1028)    
  15. char s_buf_original[MYBUFSIZE];   
  16. char r_buf_original[MYBUFSIZE];   
  17. char* machinefile = "nodes";        /* modify */   
  18. int get_first_not_used(int*,int);   
  19. double current_time(void)   
  20. {   
  21.     double timestamp;   
  22.     struct timeval tv;   
  23.    gettimeofday(&tv, 0);   
  24.    timestamp = (double)((double)(tv.tv_sec*1e6) +(double)tv.tv_usec);   
  25.     return timestamp;   
  26. }   
  27. int main(int argc,char *argv[])   
  28. {   
  29.     int myid,numprocs,stride;   
  30.     int dst,src;   
  31.     int size;   
  32.     int index,i,j;   
  33.    char* s_buf;   
  34.     char* r_buf;   
  35.     int page_size;   
  36.     double start = 0.0;   
  37.     double end = 0.0;   
  38.     MPI_Status stat[LOOP_BW];   
  39.     MPI_Request request[LOOP_BW];   
  40.     MPI_Init(&argc,&argv);   
  41.    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);   
  42.    MPI_Comm_rank(MPI_COMM_WORLD,&myid);   
  43.     int p = numprocs;   
  44.     int *use;   
  45.     int *mark;   
  46.    int *relative;   
  47.     double *result;             /* record the testing result for one thread */   
  48.     double *result_gather;   
  49.     double temp_result[6];          /* temporary result for bandwidth testing */   
  50.     int index_temp_result;   
  51. use = (int *)malloc(sizeof(int)*p);   
  52.     mark = (int *)malloc(sizeof(int)*p);   
  53.     relative = (int *)malloc(sizeof(int)*p);   
  54.     result = (double *)malloc(sizeof(double)*p);   
  55.     result_gather = (double *)malloc(sizeof(double)*p*p);   
  56.   assert(use != NULL);     
  57.   assert(mark != NULL);    
  58.   assert(relative != NULL);    
  59.  assert(result != NULL);       
  60.   assert(result_gather != NULL);       
  61.     memset(result,0x0,p*sizeof(double));   
  62.     memset(result_gather,0x0,p*p*sizeof(double));   
  63.     memset(temp_result,0x0,6*sizeof(double));   
  64.     page_size = getpagesize();   
  65.     s_buf = (char *) (((unsigned long) s_buf_original + (page_size - 1)) / page_size * page_size);   
  66.     r_buf = (char *) (((unsigned long) r_buf_original + (page_size - 1)) / page_size * page_size);   
  67.     for(stride = 1; stride < p; stride++) {   
  68.         memset(use,0x0,p*sizeof(int));   
  69.         index = get_first_not_used(use,p);   
  70.         while (index != p)   
  71.         {   
  72.             memset(relative,0x0,p*sizeof(int));   
  73.             memset(mark,0x0,p*sizeof(int));   
  74.             while(index<p)   
  75.             {   
  76.                 if((relative[index]==0)&&(use[index]==0)) {   
  77.                     use[index] = 1;   
  78.                     relative[(index + p - stride) % p] = 1;   
  79.                     relative[(index + stride) % p] = 1;   
  80.                    mark[index] = SEND;   
  81.                     mark[(index + stride ) % p] = RECV;   
  82.                 }   
  83.                 index++;   
  84.             }   
  85. #ifdef LATENCY    
  86.             size = 1;   
  87.             s_buf[0] = 'a';   
  88.             r_buf[0] = 'b';   
  89.             MPI_Barrier(MPI_COMM_WORLD);   
  90.             if (mark[myid] == SEND)   
  91.             {   
  92.                 dst = (myid+stride)%p;   
  93.             for (i = 0; i < LOOP_LAT+SKIP_LAT; i++) {   
  94.                     if(i == SKIP_LAT) start = current_time();   
  95.                     MPI_Send(s_buf, size, MPI_CHAR, dst, 1, MPI_COMM_WORLD);   
  96.                     MPI_Recv(r_buf, size, MPI_CHAR, dst, 1, MPI_COMM_WORLD, &stat[0]);   
  97.                 }   
  98.                 end = current_time();   
  99.                 result[(myid+stride)%p] = (end-start)/(2*LOOP_LAT);   
  100.             }   
  101.             if (mark[myid] == RECV)    
  102.            {   
  103.                 src = (myid+p-stride)%p;   
  104.                 for (i = 0; i < LOOP_LAT+SKIP_LAT; i++) {   
  105.                     MPI_Recv(r_buf, size, MPI_CHAR, src, 1, MPI_COMM_WORLD, &stat[0]);   
  106.                     MPI_Send(s_buf, size, MPI_CHAR, src, 1, MPI_COMM_WORLD);   
  107.                  }   
  108.             }   
  109. #endif    
  110. #ifdef BANDWIDTH    
  111.             index_temp_result = 0;   
  112.             for(size=4096; size<=4194304; size=size*4) {   
  113.             for(i=0; i<size; i++) {   
  114.                 s_buf[i] = 'a';   
  115.                 r_buf[i] = 'b';   
  116.             }   
  117.                 /*warmup */   
  118.             if (mark[myid] == SEND)   
  119.             {   
  120.                 dst = (myid+stride)%p;   
  121.                 for (i=0; i<LOOP_BW; i++) {   
  122.                     MPI_Isend(s_buf, size, MPI_CHAR, dst, 100, MPI_COMM_WORLD, request+i);   
  123.                 }   
  124.             MPI_Waitall(LOOP_BW, request, stat);   
  125.                 MPI_Recv(r_buf, 4, MPI_CHAR, dst, 101, MPI_COMM_WORLD, &stat[0]);   
  126.             }   
  127.             if (mark[myid] == RECV)   
  128.             {   
  129.                 src = (myid+p-stride)%p;   
  130.                 for (i=0; i<LOOP_BW; i++) {   
  131.                     MPI_Irecv(r_buf, size, MPI_CHAR, src, 100, MPI_COMM_WORLD, request+i);   
  132.                 }   
  133.             MPI_Waitall(LOOP_BW, request, stat);   
  134.                 MPI_Send(s_buf, 4, MPI_CHAR, src, 101, MPI_COMM_WORLD);   
  135.             }   
  136.             MPI_Barrier(MPI_COMM_WORLD);   
  137.             if (mark[myid] == SEND)   
  138.         {   
  139.                 dst = (myid+stride)%p;   
  140.                 start=current_time();   
  141.                 for (i=0; i<LOOP_BW; i++) {   
  142.                     MPI_Isend(s_buf, size, MPI_CHAR, dst, 100, MPI_COMM_WORLD, request+i);   
  143.                 }   
  144.                 MPI_Waitall(LOOP_BW, request, stat);   
  145.                 MPI_Recv(r_buf, 4, MPI_CHAR, dst, 101, MPI_COMM_WORLD, &stat[0]);   
  146.                 end=current_time();   
  147.                 temp_result[index_temp_result] = (((size*1.0))*LOOP_BW)/(end-start);   
  148.             }   
  149.             if(mark[myid] == RECV)   
  150.         {   
  151.                 src = (myid+p-stride)%p;   
  152.             for (i=0; i<LOOP_BW; i++) {   
  153.                 MPI_Irecv(r_buf, size, MPI_CHAR, src, 100, MPI_COMM_WORLD, request+i);   
  154.             }   
  155.             MPI_Waitall(LOOP_BW, request, stat);   
  156.             MPI_Send(s_buf, 4, MPI_CHAR, src, 101, MPI_COMM_WORLD);   
  157.         }   
  158.             index_temp_result++;   
  159.             }   
  160.             if(mark[myid] == SEND)   
  161.         {   
  162.                 double temp_for_exchange = 0.0;   
  163.                 for(i=0; i<index_temp_result; i++) {   
  164.                     for(j=0; j<i; j++) {   
  165.                         if(temp_result[j]>temp_result[j+1]){   
  166.                             temp_for_exchange = temp_result[j];   
  167.                             temp_result[j] = temp_result[j+1];   
  168.                             temp_result[j+1] = temp_for_exchange;   
  169.                         }   
  170.                     }   
  171.                 }   
  172.                 for(i=1; i<index_temp_result-1; i++) {   
  173.                     result[(myid+stride)%p] += temp_result[i];   
  174.                 }   
  175.                 result[(myid+stride)%p] = result[(myid+stride)%p]/(index_temp_result-2);   
  176.                 memset(temp_result,0x0,6*sizeof(double));      
  177.             }   
  178. #endif    
  179.         index = get_first_not_used(use,p);   
  180.         }   
  181.     }   
  182.     /* output the result */   
  183.     MPI_Gather(result,p,MPI_DOUBLE,result_gather,p,MPI_DOUBLE,0,MPI_COMM_WORLD);   
  184.     if(myid==0) {   
  185.         FILE* fp_out;   
  186.         FILE* fp_in;   
  187.         double sum = 0.0;   
  188.         double max = 0.0;   
  189.         int max_i;   
  190.         int max_j;   
  191.         fp_in = fopen(machinefile,"r");   
  192.         if(fp_in == NULL) {   
  193.             printf("can not open file %s\n",machinefile);   
  194.             MPI_Finalize();   
  195.             return 0;   
  196.         }   
  197.         char temp_file[10];   
  198. #ifdef LATENCY    
  199.         sprintf(temp_file,"./result.latency.%d",numprocs);   
  200. #endif    
  201. #ifdef BANDWIDTH    
  202.                sprintf(temp_file,"./result.bandwidth.%d",numprocs);   
  203. #endif    
  204. /*      strcpy(temp_file,"./result");*/   
  205.         fp_out = fopen(temp_file,"w");   
  206.     if(fp_out == NULL) {   
  207.             printf("can not create file %s\n",temp_file);   
  208.             MPI_Finalize();   
  209.             return 0;   
  210.         }   
  211.         char **name;   
  212.         name = (char **)malloc(sizeof(char *)* p);   
  213.         assert(name != NULL);   
  214.     for (i = 0; i < p; i++)  {   
  215.          name[i] = (char *)malloc(sizeof(char)*20);   
  216.          assert(name[i] != NULL);   
  217.         }   
  218.         int len;   
  219.         for(i=0; i<p; i++) {   
  220.             fgets(name[i],20,fp_in);   
  221.             len = strlen(name[i]);   
  222.             name[i][len-1] = '\0';   
  223.         }   
  224.         char *data;   
  225.         data = (char *)malloc(sizeof(char)*(20*(p+1)));   
  226.            
  227.         memset(data,0x0,20*(p+1)*sizeof(char));   
  228.         sprintf(data,"number:\t");   
  229.         for(i=0; i<p; i++) sprintf(data,"%s%s\t",data,name[i]);   
  230.         sprintf(data,"%s\n",data);   
  231.         fputs(data,fp_out);   
  232.         for(i=0; i<p; i++) {   
  233.             memset(data,0x0,20*(p+1)*sizeof(char));   
  234.             sprintf(data,"%s\t",name[i]);   
  235.             for(j=0; j<p; j++) {   
  236.             sprintf(data,"%s%.2lf\t",data,result_gather[i*p+j]);   
  237.                 sum += result_gather[i*p+j];   
  238.                 if (max > result_gather[i*p+j]) {   
  239.                     max_i = i;   
  240.                     max_j = j;   
  241.                     max = result_gather[i*p+j];   
  242.                 }   
  243.             }   
  244.                        sprintf(data,"%s\n",data);   
  245.             fputs(data,fp_out);   
  246.         }   
  247. #ifdef LATENCY    
  248.         fprintf(fp_out,"\n\n\n The average latency of the network is :%.2lf\n",sum / (p*(p-1)));   
  249.         fprintf(fp_out,"\n The Max of the latency is :(%s  to %s) = %.2lf\n", name[max_i], name[max_j],result_gather[max_i*p+max_j]);   
  250. #endif    
  251. #ifdef BANDWIDTH    
  252.                 fprintf(fp_out,"\n\n\n The average bandwidth of the network is :%.2lf\n",sum / (p*(p-1)));   
  253.                 fprintf(fp_out,"\n The Min of the bandwidth is :(%s  to %s) = %.2lf\n", name[max_i], name[max_j],result_gather[max_i*p+max_j]);   
  254. #endif    
  255.    
  256.         if(fp_in) fclose(fp_in);   
  257.         if(fp_out) fclose(fp_out);   
  258.     }   
  259.     MPI_Finalize();   
  260.     return 0;   
  261. }   
  262.    
  263. int get_first_not_used(int* use, int p)   
  264. {   
  265.     int i = 0;   
  266.     for(i=0; i<p; i++)   
  267.         if(use[i] == 0) break;   
  268.     return i;   
原创粉丝点击