// ping_pong.cc // // Ascertain bandwidth in relation to packet size #include <cstdlib> #include <iostream> #include <fstream> #include "mpi.h" using namespace std; const int max_packet_size=0x400000; // maximum size of a message const int count=100; // number of messages per measurement char buff[max_packet_size]; // Send and receive buffer int main(void) { MPI::Init(); // initialize MPI int rank=MPI::COMM_WORLD.Get_rank(); // ascertain own rank int size=MPI::COMM_WORLD.Get_size(); // and number of processes if (size==2) { // exactly two processes needed for this process ofstream out; if (rank==0) { // Open output file out.open("ping_pong.dat"); if (!out) MPI::COMM_WORLD.Abort(EXIT_FAILURE); out << "# Data throughput relative to packet size" << endl << "# Time resolution " << MPI::Wtick() << " s" << endl << "# Packet size\tmean time\tmaximum time" << endl; } // Loop through various packet sizes int packet_size=1; while (packet_size<=max_packet_size) { double t_av=0.0; double t_max=0.0; // Loop through multiple messages for (int i=0; i<count; ++i) { MPI::COMM_WORLD.Barrier(); // Synch processes // Send and/or receive messages if (rank==0) { MPI::COMM_WORLD.Barrier(); // Synch processes double t=MPI::Wtime(); // Starting time MPI::COMM_WORLD.Send(buff, packet_size, MPI::CHAR, 1, 0); MPI::COMM_WORLD.Barrier(); // Synch processes t=MPI::Wtime()-t; // Time vector t_av+=t; if (t>t_max) t_max=t; } else { MPI::COMM_WORLD.Barrier(); // Synch processes MPI::COMM_WORLD.Recv(buff, packet_size, MPI::CHAR, 0, 0); MPI::COMM_WORLD.Barrier(); // Synch processes } } if (rank==0) { // Output results t_av/=count; out << packet_size << "\t\t" << t_av << "\t" << t_max << endl; } packet_size*=2; // Double packet size } if (rank==0) // Close output file out.close(); } MPI::Finalize(); // Terminate MPI return EXIT_SUCCESS; }