summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/parallel/timing.h
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/parallel/timing.h')
-rw-r--r--libstdc++-v3/include/parallel/timing.h217
1 files changed, 217 insertions, 0 deletions
diff --git a/libstdc++-v3/include/parallel/timing.h b/libstdc++-v3/include/parallel/timing.h
new file mode 100644
index 00000000000..f1f75225c15
--- /dev/null
+++ b/libstdc++-v3/include/parallel/timing.h
@@ -0,0 +1,217 @@
+// -*- C++ -*-
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later
+// version.
+
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file parallel/timing.h
+ * @brief Provides a simple tool to do performance debugging, also in
+ * parallel code.
+ * This file is a GNU parallel extension to the Standard C++ Library.
+ */
+
+// Written by Johannes Singler.
+
+#ifndef _GLIBCXX_PARALLEL_TIMING_H
+#define _GLIBCXX_PARALLEL_TIMING_H 1
+
+#include <omp.h>
+#include <cstdio>
+#include <cstring>
+#include <parallel/tags.h>
+
+namespace __gnu_parallel
+{
+ // XXX integrate with existing performance testing infrastructure.
+ /** @brief Type of of point in time, used for the Timing classes. */
+ typedef double point_in_time;
+
+ template<typename tag, typename must_be_int = int>
+ class Timing;
+
+ /** @brief A class that provides simple run time measurements, also
+ for parallel code.
+ * @param tag If parallel_tag, then the measurements are actually done.
+ * Otherwise, no code at all is emitted by the compiler. */
+ template<typename must_be_int>
+ class Timing<parallel_tag, must_be_int>
+ {
+ private:
+ static const int max_points_in_time = 100;
+ point_in_time points_in_time[max_points_in_time];
+ point_in_time active, last_start;
+ int pos;
+ char* str;
+ const char* tags[max_points_in_time];
+
+ public:
+ Timing()
+ {
+ str = NULL;
+ pos = 0;
+ active = 0.0;
+ last_start = -1.0;
+ }
+
+ ~Timing()
+ {
+ delete[] str;
+ }
+
+ /** @brief Take a running time measurement.
+ * @param tag Optional description that will be output again with
+ * the timings.
+ * It should describe the operation before the tic(). To time a
+ * series of @c n operations, there should be @c n+1 calls to
+ * tic(), and one call to print(). */
+ inline void
+ tic(const char* tag = NULL)
+ {
+ points_in_time[pos] = omp_get_wtime();
+ tags[pos] = tag;
+ pos++;
+ }
+
+ /** @brief Start the running time measurement.
+ *
+ * Should be paired with stop(). */
+ inline void
+ start()
+ {
+ _GLIBCXX_PARALLEL_ASSERT(last_start == -1.0);
+ last_start = omp_get_wtime();
+ }
+
+ /** @brief Stop the running time measurement.
+ *
+ * Should be paired with start(). */
+ inline void
+ stop()
+ {
+ _GLIBCXX_PARALLEL_ASSERT(last_start != -1.0);
+ active += (omp_get_wtime() - last_start);
+ last_start = -1.0;
+ }
+
+ /** @brief Reset running time accumulation. */
+ inline void
+ reset()
+ {
+ active = 0.0;
+ last_start = -1.0;
+ }
+
+ /** @brief Accumulate the time between all pairs of start() and
+ stop() so far */
+ inline point_in_time
+ active_time()
+ { return active; }
+
+ /** @brief Total time between first and last tic() */
+ inline point_in_time
+ total_time()
+ { return (points_in_time[pos - 1] - points_in_time[0]) * 1000.0; }
+
+ private:
+ /** @brief Construct string to print out, presenting the timings. */
+ const char*
+ c_str()
+ {
+ // Avoid stream library here, to avoid cyclic dependencies in
+ // header files.
+ char tmp[1000];
+
+ if (!str)
+ str = new char[pos * 200];
+ else
+ str[0] = '\0';
+
+ sprintf(str, "t %2d T[ms]", omp_get_thread_num());
+ strcat(str, "\n");
+
+ for (int i = 0; i < pos; )
+ {
+ point_in_time last = points_in_time[i];
+ i++;
+ if (i == pos)
+ break;
+ if (tags[i] == NULL)
+ sprintf(tmp, "%2d: ", i - 1);
+ else
+ sprintf(tmp, "%20s: ", tags[i]);
+ strcat(str, tmp);
+
+ sprintf(tmp, "%7.2f ", (points_in_time[i] - last) * 1000.0);
+ strcat(str, tmp);
+ strcat(str, "\n");
+ }
+
+ return str;
+ }
+
+ public:
+ /** @brief Print the running times between the tic()s. */
+ void
+ print()
+ {
+ printf("print\n");
+#pragma omp barrier
+#pragma omp master
+ printf("\n\n");
+#pragma omp critical
+ printf("%s\n", c_str());
+ }
+ };
+
+ /** @brief A class that provides simple run time measurements, also
+ for parallel code.
+ * @param tag If parallel_tag, then the measurements are actually done,
+ * otherwise, no code at all is emitted by the compiler.
+ */
+ template<typename must_be_int>
+ class Timing<sequential_tag, must_be_int>
+ {
+ private:
+ static const char* empty_string;
+
+ public:
+ inline void tic(const char* /*tag*/ = NULL) { }
+ inline void start() { }
+ inline void stop() { }
+ inline void reset() { }
+ inline point_in_time active_time() { return -1.0; }
+ inline point_in_time total_time() { return -1.0; }
+ inline const char* c_str() { return empty_string; }
+ inline void print() { }
+ };
+
+ template<typename must_be_int>
+ const char* Timing<sequential_tag, must_be_int>::empty_string = "";
+
+}
+
+#endif