Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
[simgrid.git] / teshsuite / smpi / mpich3-test / perf / allredtrace.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
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
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
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;
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 }