1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *  (C) 2008 by University of Illinois
4  *      See COPYRIGHT in top-level directory.
5  */
6 
7 /*
8  * This code is intended to test the trace overhead when using an
9  * MPI tracing package.  To perform the test, follow these steps:
10  *
11  * 1) Run with the versbose mode selected to determine the delay argument
12  *    to use in subsequent tests:
13  *      mpiexec -n 4096 allredtrace -v
14  *    Assume that the computed delay count is 6237; that value is used in
15  *    the following.
16  *
17  * 2) Run with an explicit delay count, without tracing enabled:
18  *      mpiexec -n 4096 allredtrace -delaycount 6237
19  *
20  * 3) Build allredtrace with tracing enabled, then run:
21  *      mpiexec -n 4096 allredtrace -delaycount 6237
22  *
23  * Compare the total times.  The tracing version should take slightly
24  * longer but no more than, for example, 15%.
25  */
26 #include "mpi.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 static int verbose = 0;
32 static int lCount = 0;
33 void Delay( int );
34 void SetupDelay( double );
35 
main(int argc,char * argv[])36 int main( int argc, char *argv[] )
37 {
38     double usecPerCall = 100;
39     double t, t1, tsum;
40     int i, nLoop = 100;
41     int rank;
42 
43     MPI_Init( &argc, &argv );
44     MPI_Comm_rank( MPI_COMM_WORLD, &rank );
45 
46     /* Process arguments.  We allow the delay count to be set from the
47        command line to ensure reproducibility*/
48     for (i=1; i<argc; i++) {
49 	if (strcmp( argv[i], "-delaycount" ) == 0) {
50 	    i++;
51 	    lCount = atoi( argv[i] );
52 	}
53 	else if (strcmp( argv[i], "-v" ) == 0) {
54 	    verbose = 1;
55 	}
56 	else {
57 	    fprintf( stderr, "Unrecognized argument %s\n", argv[i] );
58 	    exit(1);
59 	}
60     }
61 
62     if (lCount == 0) {
63 	SetupDelay( usecPerCall );
64     }
65 
66     MPI_Barrier( MPI_COMM_WORLD );
67 
68     t = MPI_Wtime();
69     for (i=0; i<nLoop; i++) {
70 	MPI_Allreduce( &t1, &tsum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );
71 	Delay( lCount );
72     }
73     t = MPI_Wtime() - t;
74     MPI_Barrier( MPI_COMM_WORLD );
75     if (rank == 0) {
76 	printf( "For delay count %d, time is %e\n", lCount, t );
77     }
78 
79     MPI_Barrier( MPI_COMM_WORLD );
80 
81     MPI_Finalize();
82 
83     return 0;
84 }
85 
SetupDelay(double usec)86 void SetupDelay( double usec )
87 {
88     double t, tick;
89     double sec = 1.0e-6 * usec;
90     int nLoop, i, direction;
91 
92 
93     /* Compute the number of times to run the tests to get an accurate
94        number given the timer resolution. */
95     nLoop = 1;
96     tick = 100 * MPI_Wtick();
97     do {
98 	nLoop = 2 * nLoop;
99 	t = MPI_Wtime();
100 	for (i=0; i<nLoop; i++) {
101 	    MPI_Wtime();
102 	}
103 	t = MPI_Wtime() - t;
104     }
105     while ( t < tick && nLoop < 100000 );
106 
107     if (verbose) printf( "nLoop = %d\n", nLoop );
108 
109     /* Start with an estimated count */
110     lCount = 128;
111     direction = 0;
112     while (1) {
113 	t = MPI_Wtime();
114 	for (i=0; i<nLoop; i++) {
115 	    Delay( lCount );
116 	}
117 	t = MPI_Wtime() - t;
118 	t = t / nLoop;
119 	if (verbose) printf( "lCount = %d, time = %e\n", lCount, t );
120 	if (t > 10 * tick) nLoop = nLoop / 2;
121 
122 	/* Compare measured delay */
123 	if (t > 2*sec) {
124 	    lCount = lCount / 2;
125 	    if (direction == 1) break;
126 	    direction = -1;
127 	}
128 	else if (t < sec / 2) {
129 	    lCount = lCount * 2;
130 	    if (direction == -1) break;
131 	    direction = 1;
132 	}
133 	else if (t < sec) {
134 	    /* sec/2 <= t < sec , so estimate the lCount to hit sec */
135 	    lCount = (sec/t) * lCount;
136 	}
137 	else
138 	    break;
139     }
140 
141     if (verbose) printf( "lCount = %d, t = %e\n", lCount, t );
142 
143     /* Should coordinate with the other processes - take the max? */
144 }
145 
146 volatile double delayCounter = 0;
Delay(int count)147 void Delay( int count )
148 {
149     int i;
150 
151     delayCounter = 0.0;
152     for (i=0; i<count; i++) {
153 	delayCounter += 2.73;
154     }
155 }
156