2 This source code file is part of thread_mpi.
3 Written by Sander Pronk, Erik Lindahl, and possibly others.
5 Copyright (c) 2009, Sander Pronk, Erik Lindahl.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 1) Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2) Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3) Neither the name of the copyright holders nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
20 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 If you want to redistribute modifications, please consider that
31 scientific software is very special. Version control is crucial -
32 bugs must be traceable. We will be happy to consider code for
33 inclusion in the official distribution, but derived work should not
34 be called official thread_mpi. Details are found in the README & COPYING
39 /* the profiling functions. Many of these are macros, so they're inlined
40 forcibly. Profiling is turned on by defining TMPI_PROFILE, but the most
41 useful parts depend on the cycle counter, which currently only works for
42 x86, x86_64 and ia64. */
45 #include "thread_mpi/atomic/cycles.h"
51 TMPIFN_Send = 0, /* first the point-to-point comm functions */
65 TMPIFN_Barrier, /* then the barrier */
67 TMPIFN_Bcast, /* and now the collective comm functions */
82 enum tmpi_wait_functions
84 TMPIWAIT_P2p, /* p2p send wait */
85 TMPIWAIT_P2p_signal, /* p2p signaling wait */
86 TMPIWAIT_Coll_send, /* collective recv wait */
87 TMPIWAIT_Coll_recv, /* collective recv wait */
88 TMPIWAIT_Barrier, /* collective recv wait */
89 TMPIWAIT_Reduce, /* collective (all)reduce wait */
95 /* thread-specific profiling data structure */
98 unsigned long int mpifn_calls[TMPIFN_Nfunctions]; /* array of counters */
100 unsigned long int buffered_p2p_xfers; /* number of buffered p2p transfers */
101 unsigned long int total_p2p_xfers; /* total number of p2p transfers */
103 unsigned long int buffered_coll_xfers; /* number of buffered collective
105 unsigned long int total_coll_xfers; /* total number of collective
108 #ifdef TMPI_CYCLE_COUNT
110 tMPI_Cycles_t mpifn_cycles[TMPIFN_Nfunctions]; /* array of cycle counters */
111 tMPI_Cycles_t wait_cycles[TMPIWAIT_N]; /* the wait cycles */
113 tMPI_Cycles_t global_start, global_stop; /* timing start and stop times */
114 tMPI_Cycles_t mpifn_start; /* individual timing start times for profiling
115 function call times. This can be here
116 because tmpi_profile is thread-specific. */
117 enum tmpi_functions fn; /* the function being cycle-counted */
120 tMPI_Cycles_t wait_start; /* individual timing start times for profiling
123 double totals; /* totals counter for reporting end results */
127 extern int tMPI_Profile_started;
129 /* initialize the profile counter */
130 int tMPI_Profile_init(struct tmpi_profile *prof);
134 void tMPI_Profile_destroy(struct tmpi_profile *prof);
138 void tMPI_Profile_stop(struct tmpi_profile *prof);
142 /* counter functions */
144 #ifdef TMPI_CYCLE_COUNT
145 /*void tMPI_Profile_count_start(struct tmpi_thread *th);*/
146 #define tMPI_Profile_count_start(th) { th->profile.mpifn_start = tMPI_Cycles_read(); }
148 #define tMPI_Profile_count_start(th) {}
151 /* end. this is where the counting actually happens */
152 /*void tMPI_Profile_count_stop(struct tmpi_thread *th, enum tmpi_functions fn);*/
153 #ifdef TMPI_CYCLE_COUNT
154 #define tMPI_Profile_count_stop(th, fn) \
156 tMPI_Cycles_t stop = tMPI_Cycles_read(); \
157 th->profile.mpifn_cycles[fn] += (stop - th->profile.mpifn_start); \
158 (th->profile.mpifn_calls[fn])++; \
161 #define tMPI_Profile_count_stop(th, fn) \
163 (th->profile.mpifn_calls[fn])++; \
174 #ifdef TMPI_CYCLE_COUNT
175 /* start waiting cycle count */
176 /*void tMPI_Profile_wait_start(struct tmpi_thread *th);*/
177 #define tMPI_Profile_wait_start(th) \
179 th->profile.wait_start = tMPI_Cycles_read(); \
182 /* stop waiting cycle count */
183 /*void tMPI_Profile_wait_stop(struct tmpi_thread *th,
184 enum tmpi_wait_functions fn);*/
185 #define tMPI_Profile_wait_stop(th, fn) \
187 tMPI_Cycles_t wait_stop = tMPI_Cycles_read(); \
188 th->profile.wait_cycles[fn] += (wait_stop - th->profile.wait_start); \
191 #define tMPI_Profile_wait_start(th) {}
192 #define tMPI_Profile_wait_stop(th, fn) {}
196 /* count the number of transfers at the receiving end. */
197 /*void tMPI_Profile_count_buffered_p2p_xfer(struct tmpi_thread *th);
198 void tMPI_Profile_count_p2p_xfer(struct tmpi_thread *th);
199 void tMPI_Profile_count_buffered_coll_xfer(struct tmpi_thread *th);
200 void tMPI_Profile_count_coll_xfer(struct tmpi_thread *th);*/
201 #define tMPI_Profile_count_buffered_p2p_xfer(th) \
203 (th->profile.buffered_p2p_xfers)++; \
206 #define tMPI_Profile_count_p2p_xfer(th) \
208 (th->profile.total_p2p_xfers)++; \
211 #define tMPI_Profile_count_buffered_coll_xfer(th) \
213 (th->profile.buffered_coll_xfers)++; \
216 #define tMPI_Profile_count_coll_xfer(th) \
218 (th->profile.total_coll_xfers)++; \
223 /* output functions */
224 void tMPI_Profiles_summarize(int Nthreads, struct tmpi_thread *threads);