next up previous
Next: 考察 Up: koukyu_throughput Previous: グラフ

プログラム

最終的にMPI_Sendでやりとりするデータ量(KB)と時間、スループット(MB/s)を表示するようにした。 通信は1回のピンポン通信である。

MPI_Sendでやりとりするデータ量(KB)が大きくなるということは、パケットのサイズが大きくなるということ。 0〜1024KBの間を4KBづつずらして観察した。

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DEFAULT_SIZE 1024
#define KB 1024
#define MB 1048576

int main(int argc, char *argv[]){
  int numprocs, namelen, myid;
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  double wtime, timer, sum, zero_timer, zero_wtime, s;

  int try;
  int i, j, k;
  char *packet;
  MPI_Status status;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  MPI_Get_processor_name(processor_name, &namelen);

  /*
  if(numprocs != 2){
    if(myid == 0){
      printf("Sorry, This program runs only in the case of using 2 PEs.\n");
    }
    MPI_Finalize();
    exit(0);
  }
  */

  fprintf(stdout, "Process %d of %d on %s\n", myid, numprocs, processor_name);
   fprintf(stdout, "## Datasize(KB)\tThroughput(MB/s)\n");
     fflush(stdout);


  packet = (char *) malloc(KB * KB);       // 1024KB
  //  try = 100;
  try = 100;

  /* warm-up */
  if(myid == 0){
    MPI_Send(packet, KB * KB, MPI_BYTE, 1, 4040, MPI_COMM_WORLD);
    MPI_Recv(packet, KB * KB, MPI_BYTE, 1, 4050, MPI_COMM_WORLD, &status);
  }
  else if(myid == 1){
    MPI_Recv(packet, KB * KB, MPI_BYTE, 0, 4040, MPI_COMM_WORLD, &status);
    MPI_Send(packet, KB * KB, MPI_BYTE, 0, 4050, MPI_COMM_WORLD);
  }



  /* i byte ping-pong */


  for(i = 0; i <= 1024 * KB; i += 4 * KB){
    sum = 0.0;
   wtime = 0.0;

   for(j = 0; j < try; j++){
     if(myid % 2 == 0){
        timer = MPI_Wtime();

        MPI_Send(packet, i, MPI_BYTE, myid+1, 4040, MPI_COMM_WORLD);
        MPI_Recv(packet, i, MPI_BYTE, myid+1, 4050, MPI_COMM_WORLD, &status);

        MPI_Barrier(MPI_COMM_WORLD);
        wtime = MPI_Wtime() - timer;
        sum += wtime;
      }
      else if(myid % 2 == 1){
        MPI_Recv(packet, i, MPI_BYTE, myid-1, 4040, MPI_COMM_WORLD, &status);
        MPI_Send(packet, i, MPI_BYTE, myid-1, 4050, MPI_COMM_WORLD);
        MPI_Barrier(MPI_COMM_WORLD);
      }
    }
    /* output results */
   for(j=0;j<numprocs/2;j++){
     MPI_Barrier(MPI_COMM_WORLD);
    if(myid == 2 * j){
      s = sum / 2.0 / try;
      fprintf(stdout, "%d\t%4d\t%10.6f\t%f ",myid, i / KB,
              s,i / s / MB);
      fflush(stdout);
      if(myid + 2 >= numprocs){
        fprintf(stdout, "\n");
        fflush(stdout);
      }
    }

         }


    MPI_Barrier(MPI_COMM_WORLD);
  }

  /* Finallize */
  MPI_Finalize();
  return 0;
}
表示するときに同期を取りたかったためMPI_Barrierが多く使ってある。 このため動作が少し遅くなった。

s.tobita
平成15年12月5日