OSDN Git Service

f1f75225c156eab16c581fe5a35e61bcf9cb4d12
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / parallel / timing.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2007 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 2, or (at your option) any later
9 // version.
10
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING.  If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 // MA 02111-1307, USA.
20
21 // As a special exception, you may use this file as part of a free
22 // software library without restriction.  Specifically, if other files
23 // instantiate templates or use macros or inline functions from this
24 // file, or you compile this file and link it with other files to
25 // produce an executable, this file does not by itself cause the
26 // resulting executable to be covered by the GNU General Public
27 // License.  This exception does not however invalidate any other
28 // reasons why the executable file might be covered by the GNU General
29 // Public License.
30
31 /** @file parallel/timing.h
32  *  @brief Provides a simple tool to do performance debugging, also in
33  *  parallel code.
34  *  This file is a GNU parallel extension to the Standard C++ Library.
35  */
36
37 // Written by Johannes Singler.
38
39 #ifndef _GLIBCXX_PARALLEL_TIMING_H
40 #define _GLIBCXX_PARALLEL_TIMING_H 1
41
42 #include <omp.h>
43 #include <cstdio>
44 #include <cstring>
45 #include <parallel/tags.h>
46
47 namespace __gnu_parallel
48 {
49   // XXX integrate with existing performance testing infrastructure.
50   /** @brief Type of of point in time, used for the Timing classes. */
51   typedef double point_in_time;
52
53   template<typename tag, typename must_be_int = int>
54   class Timing;
55
56   /** @brief A class that provides simple run time measurements, also
57       for parallel code.
58    *  @param tag If parallel_tag, then the measurements are actually done.
59    *  Otherwise, no code at all is emitted by the compiler. */
60   template<typename must_be_int>
61   class Timing<parallel_tag, must_be_int>
62   {
63   private:
64     static const int max_points_in_time = 100;
65     point_in_time points_in_time[max_points_in_time];
66     point_in_time active, last_start;
67     int pos;
68     char* str;
69     const char* tags[max_points_in_time];
70
71   public:
72     Timing()
73     {
74       str = NULL;
75       pos = 0;
76       active = 0.0;
77       last_start = -1.0;
78     }
79
80     ~Timing()
81     {
82       delete[] str;
83     }
84
85     /** @brief Take a running time measurement.
86      *  @param tag Optional description that will be output again with
87      *  the timings.
88      *  It should describe the operation before the tic(). To time a
89      *  series of @c n operations, there should be @c n+1 calls to
90      *  tic(), and one call to print(). */
91     inline void
92     tic(const char* tag = NULL)
93     {
94       points_in_time[pos] = omp_get_wtime();
95       tags[pos] = tag;
96       pos++;
97     }
98
99     /** @brief Start the running time measurement.
100      *
101      *  Should be paired with stop(). */
102     inline void
103     start()
104     {
105       _GLIBCXX_PARALLEL_ASSERT(last_start == -1.0);
106       last_start = omp_get_wtime();
107     }
108
109     /** @brief Stop the running time measurement.
110      *
111      *  Should be paired with start(). */
112     inline void
113     stop()
114     {
115       _GLIBCXX_PARALLEL_ASSERT(last_start != -1.0);
116       active += (omp_get_wtime() - last_start);
117       last_start = -1.0;
118     }
119
120     /** @brief Reset running time accumulation. */
121     inline void
122     reset()
123     {
124       active = 0.0;
125       last_start = -1.0;
126     }
127
128     /** @brief Accumulate the time between all pairs of start() and
129         stop() so far */
130     inline point_in_time
131     active_time()
132     { return active; }
133
134     /** @brief Total time between first and last tic() */
135     inline point_in_time
136     total_time()
137     { return (points_in_time[pos - 1] - points_in_time[0]) * 1000.0; }
138
139   private:
140     /** @brief Construct string to print out, presenting the timings. */
141     const char*
142     c_str()
143     {
144       // Avoid stream library here, to avoid cyclic dependencies in
145       // header files.
146       char tmp[1000];
147
148       if (!str)
149         str = new char[pos * 200];
150       else
151         str[0] = '\0';
152
153       sprintf(str, "t %2d      T[ms]", omp_get_thread_num());
154       strcat(str, "\n");
155
156       for (int i = 0; i < pos; )
157         {
158           point_in_time last = points_in_time[i];
159           i++;
160           if (i == pos)
161             break;
162           if (tags[i] == NULL)
163             sprintf(tmp, "%2d:     ", i - 1);
164           else
165             sprintf(tmp, "%20s:     ", tags[i]);
166           strcat(str, tmp);
167
168           sprintf(tmp, "%7.2f     ", (points_in_time[i] - last) * 1000.0);
169           strcat(str, tmp);
170           strcat(str, "\n");
171         }
172
173       return str;
174     }
175
176   public:
177     /** @brief Print the running times between the tic()s. */
178     void
179     print()
180     {
181       printf("print\n");
182 #pragma omp barrier
183 #pragma omp master
184       printf("\n\n");
185 #pragma omp critical
186       printf("%s\n", c_str());
187     }
188   };
189
190   /** @brief A class that provides simple run time measurements, also
191       for parallel code.
192    *  @param tag If parallel_tag, then the measurements are actually done,
193    *  otherwise, no code at all is emitted by the compiler.
194    */
195   template<typename must_be_int>
196   class Timing<sequential_tag, must_be_int>
197   {
198   private:
199     static const char* empty_string;
200
201   public:
202     inline void tic(const char* /*tag*/ = NULL) { }
203     inline void start() { }
204     inline void stop() { }
205     inline void reset() { }
206     inline point_in_time active_time() { return -1.0; }
207     inline point_in_time total_time() { return -1.0; }
208     inline const char* c_str() { return empty_string; }
209     inline void print() { }
210   };
211
212   template<typename must_be_int>
213   const char* Timing<sequential_tag, must_be_int>::empty_string = "";
214
215 }
216
217 #endif