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