]> git.cworth.org Git - fips/blobdiff - metrics.c
Simplify metrics interface by dropping metrics_counter_new
[fips] / metrics.c
index 84fc23f6b20b02a2a15ece51ee9b63447d4e5466..39c90ad1145547846da59dac480a6e711e4a846c 100644 (file)
--- a/metrics.c
+++ b/metrics.c
@@ -19,6 +19,8 @@
  * THE SOFTWARE.
  */
 
+#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -37,8 +39,11 @@ typedef struct counter
 
 typedef struct program_metrics
 {
+       /* This happens to also be the index into the
+        * ctx->program_metrics array currently
+        */
        unsigned id;
-       double ticks;
+       double time_ns;
 } program_metrics_t;
 
 typedef struct context
@@ -57,8 +62,11 @@ typedef struct context
 
 context_t current_context;
 
-unsigned
-metrics_counter_new (void)
+int frames;
+int verbose;
+
+void
+metrics_counter_start (void)
 {
        counter_t *counter;
 
@@ -81,13 +89,7 @@ metrics_counter_new (void)
                current_context.counter_head = counter;
        }
 
-       return counter->id;
-}
-
-void
-metrics_counter_start (unsigned counter)
-{
-       glBeginQuery (GL_TIME_ELAPSED, counter);
+       glBeginQuery (GL_TIME_ELAPSED, counter->id);
 }
 
 void
@@ -103,7 +105,7 @@ metrics_set_current_program (unsigned program)
 }
 
 static void
-accumulate_program_ticks (unsigned program_id, unsigned ticks)
+accumulate_program_time (unsigned program_id, unsigned time_ns)
 {
        context_t *ctx = &current_context;
        unsigned i;
@@ -113,43 +115,89 @@ accumulate_program_ticks (unsigned program_id, unsigned ticks)
                                                (program_id + 1) * sizeof (program_metrics_t));
                for (i = ctx->num_program_metrics; i < program_id + 1; i++) {
                        ctx->program_metrics[i].id = i;
-                       ctx->program_metrics[i].ticks = 0.0;
+                       ctx->program_metrics[i].time_ns = 0.0;
                }
 
                ctx->num_program_metrics = program_id + 1;
        }
 
-       ctx->program_metrics[program_id].ticks += ticks;
+       ctx->program_metrics[program_id].time_ns += time_ns;
+}
+
+static int
+time_compare(const void *in_a, const void *in_b, void *arg)
+{
+       int a = *(const int *)in_a;
+       int b = *(const int *)in_b;
+       struct program_metrics *metrics = arg;
+
+       if (metrics[a].time_ns < metrics[b].time_ns)
+               return -1;
+       if (metrics[a].time_ns > metrics[b].time_ns)
+               return 1;
+       return 0;
 }
 
-/* FIXME: Should sort the metrics, print out percentages, etc. */
 static void
 print_program_metrics (void)
 {
        context_t *ctx = &current_context;
        unsigned i;
+       int *sorted; /* Sorted indices into the ctx->program_metrics */
+       double total = 0;
 
+       /* Make a sorted list of the programs by time used, and figure
+        * out to total so we can print percentages.
+        */
+       sorted = calloc(ctx->num_program_metrics, sizeof(*sorted));
        for (i = 0; i < ctx->num_program_metrics; i++) {
-               if (ctx->program_metrics[i].ticks == 0.0)
+               sorted[i] = i;
+               total += ctx->program_metrics[i].time_ns;
+       }
+       qsort_r(sorted, ctx->num_program_metrics, sizeof(*sorted),
+               time_compare, ctx->program_metrics);
+
+       for (i = 0; i < ctx->num_program_metrics; i++) {
+               struct program_metrics *metric =
+                       &ctx->program_metrics[sorted[i]];
+
+               /* Since we sparsely fill the array based on program
+                * id, many "programs" have no time.
+                */
+               if (metric->time_ns == 0.0)
                        continue;
-               printf ("Program %d:\t%7.2f mega-ticks\n",
-                       i, ctx->program_metrics[i].ticks / 1e6);
+
+               printf ("Program %d:\t%7.2f ms (% 2.1f%%)\n",
+                       metric->id, metric->time_ns / 1e6,
+                       metric->time_ns / total * 100);
        }
 }
 
+/* Called at program exit */
+static void
+metrics_exit (void)
+{
+       if (verbose)
+               printf ("fips: terminating\n");
+}
+
+
 void
 metrics_end_frame (void)
 {
        static int initialized = 0;
-       static int frames;
        static struct timeval tv_start, tv_now;
 
        if (! initialized) {
-               frames = 0;
                gettimeofday (&tv_start, NULL);
+               atexit (metrics_exit);
+               if (getenv ("FIPS_VERBOSE"))
+                       verbose = 1;
                initialized = 1;
        }
 
+       if (verbose)
+               printf ("fips: frame %d complete\n", frames);
 
        frames++;
        gettimeofday (&tv_now, NULL);
@@ -167,7 +215,7 @@ metrics_end_frame (void)
 
                glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed);
 
-               accumulate_program_ticks (counter->program, elapsed);
+               accumulate_program_time (counter->program, elapsed);
 
                current_context.counter_head = counter->next;
                if (current_context.counter_head == NULL)