static char rcsid[] =
"$Id: bwtest.c,v 1.11 1999/03/15 19:04:18 pvmsrc Exp $";
/*
* PVM version 3.4: Parallel Virtual Machine System
* University of Tennessee, Knoxville TN.
* Oak Ridge National Laboratory, Oak Ridge TN.
* Emory University, Atlanta GA.
* Authors: J. J. Dongarra, G. E. Fagg, M. Fischer
* G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
* P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
* (C) 1997 All Rights Reserved
*
* NOTICE
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted
* provided that the above copyright notice appear in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* Neither the Institutions (Emory University, Oak Ridge National
* Laboratory, and University of Tennessee) nor the Authors make any
* representations about the suitability of this software for any
* purpose. This software is provided ``as is'' without express or
* implied warranty.
*
* PVM version 3 was funded in part by the U.S. Department of Energy,
* the National Science Foundation and the State of Tennessee.
*/
/* bwtest.c - bandwidth tester
* This is yet another bandwidth tester.
* It measures user-space to user-space times.
*
* The measurement is a standard ping-pong with roundtrip time measured
* from the originating sender.
*
* This is a PVM test code
*/
#include "pvm3.h"
#include "stdio.h" /* needed to help 64bit compilers understand printf */
#ifndef SAMPLE
#define SAMPLE 20 /* sample rate */
#endif
#ifndef MAXSIZE
#define MAXSIZE 100000 /* must be a power of 10 */
#endif
#define VTAG 10
#define MTAG 100
#ifndef ENCODE
#define ENCODE PvmDataInPlace
#endif
#define GETTIME(_x,_y) pvmgetclock((_x))
#ifndef WIN32
#include <sys/time.h>
#else
#include <winsock.h>
#endif
struct timeval tv1, tv2;
#define TIMER_CLEAR (tv1.tv_sec = tv1.tv_usec = tv2.tv_sec = tv2.tv_usec =0)
#define TIMER_START GETTIME(&tv1, (struct timezone*)0)
#define TIMER_STOP GETTIME(&tv2, (struct timezone*)0)
#define TIMER_ELAPSED \
( ( tv2.tv_usec - tv1.tv_usec ) \
+ ( ( tv2.tv_sec - tv1.tv_sec) * 1.E6 ) )
#define GNAME "bwtest"
void pingpong(); /* where all the work is done and measured */
main(argc, argv)
int argc;
char *argv[];
{
int mytid;
int myinst;
int othertid;
int otherinst;
if ((mytid = pvm_mytid()) < 0)
exit(-1);
if((myinst = pvm_joingroup(GNAME)) < 0) {
pvm_perror("Error joining bwtest group");
exit(-1);
}
printf(" %x myinst is %d \n", mytid, myinst);
switch (myinst % 2) {
case 0:
otherinst = myinst + 1;
while ((othertid = pvm_gettid(GNAME, otherinst)) < 0)
pvmsleep(1);
pingpong(mytid, othertid);
break;
case 1:
otherinst = myinst - 1;
while ((othertid = pvm_gettid(GNAME, otherinst)) < 0)
pvmsleep(1);
pingpong(othertid, mytid);
break;
}
pvm_lvgroup(GNAME);
pvm_exit();
}
void
validate(data, size)
double data[];
int size;
{
int i;
int mytid;
mytid = pvm_mytid();
for (i = 0; i < size; i++)
if ((i*i - data[i]) > 0.01) {
printf("error: data[%d] = %g\n", i, data[i]);
break;
}
if (i == size)
printf("t%x: %d doubles received correctly\n\n\n", mytid, i);
}
/* exchange messages and measure the transit time */
void
pingpong(mastertid, slavetid)
int mastertid;
int slavetid;
{
int ismaster;
int mytid;
int n;
int size;
int t;
static double data[MAXSIZE];
char str[32];
/* test node-to-node send */
mytid = pvm_mytid();
ismaster = ( mytid == mastertid );
if (ismaster)
{
#ifdef PACK
print_header(ENCODE, MAXSIZE*sizeof(double), SAMPLE);
#else
print_header(-1, MAXSIZE*sizeof(double), SAMPLE);
#endif
}
printf("%x -- I am the %s \n", mytid, (ismaster ? "master" : "slave"));
/* first validate that all doubles are sent and returned correctly */
if (ismaster)
{
for (n = 0; n < MAXSIZE; n++)
data[n] = n*n;
#ifdef PACK
pvm_initsend(ENCODE);
pvm_pkdouble(data, MAXSIZE, 1);
pvm_send(slavetid, VTAG); /* send the data */
pvm_recv(slavetid, VTAG); /* recv it back and validate */
pvm_upkdouble(data, MAXSIZE, 1);
#else
pvm_psend(slavetid, VTAG, data, MAXSIZE, PVM_DOUBLE);
pvm_precv(slavetid, VTAG, data, MAXSIZE, PVM_DOUBLE, (int*)0,
(int*)0, (int*)0);
#endif
}
else
{
#ifdef PACK
pvm_recv(mastertid, VTAG); /* recv and unpack */
pvm_upkdouble(data, MAXSIZE, 1);
pvm_initsend(ENCODE); /* echo */
pvm_pkdouble(data, MAXSIZE, 1);
pvm_send(mastertid, VTAG); /* send the data */
#else
pvm_precv(mastertid, VTAG, data, MAXSIZE, PVM_DOUBLE, (int*)0,
(int*)0, (int*)0);
pvm_psend(mastertid, VTAG, data, MAXSIZE, PVM_DOUBLE);
#endif
}
validate(data, MAXSIZE);
sprintf(str, "%d doubles from t%x", MAXSIZE, slavetid);
/* now do the ping-pong */
for (size = 0; size <= MAXSIZE; size = ( size ? 10*size : 1) )
{
TIMER_CLEAR;
TIMER_START;
for (n = 0; n < SAMPLE; n++)
{
if (ismaster)
{
#ifdef PACK
pvm_initsend(ENCODE);
pvm_pkdouble(data, size, 1);
pvm_send(slavetid, MTAG);
pvm_recv(slavetid, MTAG);
pvm_upkdouble(data, size, 1);
#else
pvm_psend(slavetid, MTAG, data, size, PVM_DOUBLE);
pvm_precv(slavetid, MTAG, data, size, PVM_DOUBLE,
(int*)0, (int*)0, (int*)0);
#endif /*PACK*/
}
else
{
#ifdef PACK
pvm_recv(mastertid, MTAG);
pvm_upkdouble(data, size, 1);
pvm_initsend(ENCODE);
pvm_pkdouble(data, size, 1);
pvm_send(mastertid, MTAG);
#else
pvm_precv(mastertid, MTAG, data, size, PVM_DOUBLE,
(int*)0, (int*)0, (int*)0);
pvm_psend(mastertid, MTAG, data, size, PVM_DOUBLE);
#endif /*PACK*/
}
}
if (ismaster)
{
TIMER_STOP;
t = (int) TIMER_ELAPSED / SAMPLE;
printf("Roundtrip T = %d (us) (%.4f MB/s) Data size: %d\n",
t, 2.0*8.0*(float)size/(float)t, ((int)sizeof(double))*size);
}
}
}
int
print_header(packtype, size, niter)
int packtype;
int size;
int niter;
{
printf("--- Simple PVM Bandwidth Test ----\n");
printf(" Using pack option: %s \n",
(packtype == PvmDataRaw ? "PvmDataRaw" :
(packtype == PvmDataInPlace ? "PvmDataInPlace" :
(packtype == PvmDataDefault ? "PvmDataDefault" :
(packtype == -1 ? "Psend/Precv" : "Unknown")))));
printf(" Max data size is: %d \n", size);
printf(" Number of iterations/sample: %d \n", niter);
printf(" \n\n");
printf(" Roundtrip time is measured from user-space to user-space.\n");
if ( packtype != -1)
{
printf(" For packed messages this includes the combined time of: \n");
printf(" inst 0: pvm_initsend() \n");
printf(" inst 0: pvm_pack() \n");
printf(" inst 0: pvm_send() \n");
printf(" inst 1: pvm_recv() \n");
printf(" inst 1: pvm_unpack() \n");
printf(" inst 1: pvm_initsend() \n");
printf(" inst 1: pvm_pack() \n");
printf(" inst 1: pvm_send() \n");
printf(" inst 0: pvm_recv() \n");
printf(" inst 0: pvm_unpack() \n");
}
else
{
printf(" For pvm_psend/precv this includes the combined time of: \n");
printf(" inst 0: pvm_psend() \n");
printf(" inst 1: pvm_precv() \n");
printf(" inst 1: pvm_psend() \n");
printf(" inst 0: pvm_precv() \n");
}
printf("\n\n---------------------------------------\n");
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1