- #include <stdlib.h>
- #include <stdio.h>
- #include <memory.h>
- #include <math.h>
- #include <unistd.h>
- #include <mpi.h>
- #include <assert.h>
- #include <sys/time.h>
- #define SEND 1
- #define RECV 2
- #define LOOP_LAT 10000
- #define SKIP_LAT 100
- #define LOOP_BW 25
- #define MYBUFSIZE (4*1024*1028)
- char s_buf_original[MYBUFSIZE];
- char r_buf_original[MYBUFSIZE];
- char* machinefile = "nodes"; /* modify */
- int get_first_not_used(int*,int);
- double current_time(void)
- {
- double timestamp;
- struct timeval tv;
- gettimeofday(&tv, 0);
- timestamp = (double)((double)(tv.tv_sec*1e6) +(double)tv.tv_usec);
- return timestamp;
- }
- int main(int argc,char *argv[])
- {
- int myid,numprocs,stride;
- int dst,src;
- int size;
- int index,i,j;
- char* s_buf;
- char* r_buf;
- int page_size;
- double start = 0.0;
- double end = 0.0;
- MPI_Status stat[LOOP_BW];
- MPI_Request request[LOOP_BW];
- MPI_Init(&argc,&argv);
- MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
- MPI_Comm_rank(MPI_COMM_WORLD,&myid);
- int p = numprocs;
- int *use;
- int *mark;
- int *relative;
- double *result; /* record the testing result for one thread */
- double *result_gather;
- double temp_result[6]; /* temporary result for bandwidth testing */
- int index_temp_result;
- use = (int *)malloc(sizeof(int)*p);
- mark = (int *)malloc(sizeof(int)*p);
- relative = (int *)malloc(sizeof(int)*p);
- result = (double *)malloc(sizeof(double)*p);
- result_gather = (double *)malloc(sizeof(double)*p*p);
- assert(use != NULL);
- assert(mark != NULL);
- assert(relative != NULL);
- assert(result != NULL);
- assert(result_gather != NULL);
- memset(result,0x0,p*sizeof(double));
- memset(result_gather,0x0,p*p*sizeof(double));
- memset(temp_result,0x0,6*sizeof(double));
- page_size = getpagesize();
- s_buf = (char *) (((unsigned long) s_buf_original + (page_size - 1)) / page_size * page_size);
- r_buf = (char *) (((unsigned long) r_buf_original + (page_size - 1)) / page_size * page_size);
- for(stride = 1; stride < p; stride++) {
- memset(use,0x0,p*sizeof(int));
- index = get_first_not_used(use,p);
- while (index != p)
- {
- memset(relative,0x0,p*sizeof(int));
- memset(mark,0x0,p*sizeof(int));
- while(index<p)
- {
- if((relative[index]==0)&&(use[index]==0)) {
- use[index] = 1;
- relative[(index + p - stride) % p] = 1;
- relative[(index + stride) % p] = 1;
- mark[index] = SEND;
- mark[(index + stride ) % p] = RECV;
- }
- index++;
- }
- #ifdef LATENCY
- size = 1;
- s_buf[0] = 'a';
- r_buf[0] = 'b';
- MPI_Barrier(MPI_COMM_WORLD);
- if (mark[myid] == SEND)
- {
- dst = (myid+stride)%p;
- for (i = 0; i < LOOP_LAT+SKIP_LAT; i++) {
- if(i == SKIP_LAT) start = current_time();
- MPI_Send(s_buf, size, MPI_CHAR, dst, 1, MPI_COMM_WORLD);
- MPI_Recv(r_buf, size, MPI_CHAR, dst, 1, MPI_COMM_WORLD, &stat[0]);
- }
- end = current_time();
- result[(myid+stride)%p] = (end-start)/(2*LOOP_LAT);
- }
- if (mark[myid] == RECV)
- {
- src = (myid+p-stride)%p;
- for (i = 0; i < LOOP_LAT+SKIP_LAT; i++) {
- MPI_Recv(r_buf, size, MPI_CHAR, src, 1, MPI_COMM_WORLD, &stat[0]);
- MPI_Send(s_buf, size, MPI_CHAR, src, 1, MPI_COMM_WORLD);
- }
- }
- #endif
- #ifdef BANDWIDTH
- index_temp_result = 0;
- for(size=4096; size<=4194304; size=size*4) {
- for(i=0; i<size; i++) {
- s_buf[i] = 'a';
- r_buf[i] = 'b';
- }
- /*warmup */
- if (mark[myid] == SEND)
- {
- dst = (myid+stride)%p;
- for (i=0; i<LOOP_BW; i++) {
- MPI_Isend(s_buf, size, MPI_CHAR, dst, 100, MPI_COMM_WORLD, request+i);
- }
- MPI_Waitall(LOOP_BW, request, stat);
- MPI_Recv(r_buf, 4, MPI_CHAR, dst, 101, MPI_COMM_WORLD, &stat[0]);
- }
- if (mark[myid] == RECV)
- {
- src = (myid+p-stride)%p;
- for (i=0; i<LOOP_BW; i++) {
- MPI_Irecv(r_buf, size, MPI_CHAR, src, 100, MPI_COMM_WORLD, request+i);
- }
- MPI_Waitall(LOOP_BW, request, stat);
- MPI_Send(s_buf, 4, MPI_CHAR, src, 101, MPI_COMM_WORLD);
- }
- MPI_Barrier(MPI_COMM_WORLD);
- if (mark[myid] == SEND)
- {
- dst = (myid+stride)%p;
- start=current_time();
- for (i=0; i<LOOP_BW; i++) {
- MPI_Isend(s_buf, size, MPI_CHAR, dst, 100, MPI_COMM_WORLD, request+i);
- }
- MPI_Waitall(LOOP_BW, request, stat);
- MPI_Recv(r_buf, 4, MPI_CHAR, dst, 101, MPI_COMM_WORLD, &stat[0]);
- end=current_time();
- temp_result[index_temp_result] = (((size*1.0))*LOOP_BW)/(end-start);
- }
- if(mark[myid] == RECV)
- {
- src = (myid+p-stride)%p;
- for (i=0; i<LOOP_BW; i++) {
- MPI_Irecv(r_buf, size, MPI_CHAR, src, 100, MPI_COMM_WORLD, request+i);
- }
- MPI_Waitall(LOOP_BW, request, stat);
- MPI_Send(s_buf, 4, MPI_CHAR, src, 101, MPI_COMM_WORLD);
- }
- index_temp_result++;
- }
- if(mark[myid] == SEND)
- {
- double temp_for_exchange = 0.0;
- for(i=0; i<index_temp_result; i++) {
- for(j=0; j<i; j++) {
- if(temp_result[j]>temp_result[j+1]){
- temp_for_exchange = temp_result[j];
- temp_result[j] = temp_result[j+1];
- temp_result[j+1] = temp_for_exchange;
- }
- }
- }
- for(i=1; i<index_temp_result-1; i++) {
- result[(myid+stride)%p] += temp_result[i];
- }
- result[(myid+stride)%p] = result[(myid+stride)%p]/(index_temp_result-2);
- memset(temp_result,0x0,6*sizeof(double));
- }
- #endif
- index = get_first_not_used(use,p);
- }
- }
- /* output the result */
- MPI_Gather(result,p,MPI_DOUBLE,result_gather,p,MPI_DOUBLE,0,MPI_COMM_WORLD);
- if(myid==0) {
- FILE* fp_out;
- FILE* fp_in;
- double sum = 0.0;
- double max = 0.0;
- int max_i;
- int max_j;
- fp_in = fopen(machinefile,"r");
- if(fp_in == NULL) {
- printf("can not open file %s\n",machinefile);
- MPI_Finalize();
- return 0;
- }
- char temp_file[10];
- #ifdef LATENCY
- sprintf(temp_file,"./result.latency.%d",numprocs);
- #endif
- #ifdef BANDWIDTH
- sprintf(temp_file,"./result.bandwidth.%d",numprocs);
- #endif
- /* strcpy(temp_file,"./result");*/
- fp_out = fopen(temp_file,"w");
- if(fp_out == NULL) {
- printf("can not create file %s\n",temp_file);
- MPI_Finalize();
- return 0;
- }
- char **name;
- name = (char **)malloc(sizeof(char *)* p);
- assert(name != NULL);
- for (i = 0; i < p; i++) {
- name[i] = (char *)malloc(sizeof(char)*20);
- assert(name[i] != NULL);
- }
- int len;
- for(i=0; i<p; i++) {
- fgets(name[i],20,fp_in);
- len = strlen(name[i]);
- name[i][len-1] = '\0';
- }
- char *data;
- data = (char *)malloc(sizeof(char)*(20*(p+1)));
- memset(data,0x0,20*(p+1)*sizeof(char));
- sprintf(data,"number:\t");
- for(i=0; i<p; i++) sprintf(data,"%s%s\t",data,name[i]);
- sprintf(data,"%s\n",data);
- fputs(data,fp_out);
- for(i=0; i<p; i++) {
- memset(data,0x0,20*(p+1)*sizeof(char));
- sprintf(data,"%s\t",name[i]);
- for(j=0; j<p; j++) {
- sprintf(data,"%s%.2lf\t",data,result_gather[i*p+j]);
- sum += result_gather[i*p+j];
- if (max > result_gather[i*p+j]) {
- max_i = i;
- max_j = j;
- max = result_gather[i*p+j];
- }
- }
- sprintf(data,"%s\n",data);
- fputs(data,fp_out);
- }
- #ifdef LATENCY
- fprintf(fp_out,"\n\n\n The average latency of the network is :%.2lf\n",sum / (p*(p-1)));
- 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]);
- #endif
- #ifdef BANDWIDTH
- fprintf(fp_out,"\n\n\n The average bandwidth of the network is :%.2lf\n",sum / (p*(p-1)));
- 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]);
- #endif
- if(fp_in) fclose(fp_in);
- if(fp_out) fclose(fp_out);
- }
- MPI_Finalize();
- return 0;
- }
- int get_first_not_used(int* use, int p)
- {
- int i = 0;
- for(i=0; i<p; i++)
- if(use[i] == 0) break;
- return i;
- }
mpi连接性能测试
最新推荐文章于 2024-03-28 16:04:06 发布