source: trunk/lib/perflib/WallTime.h

Last change on this file was 2479, checked in by lindanl, 7 years ago

Change to static functions.

File size: 5.4 KB
Line 
1/*
2    WallTime.h - Binary Order of Magnitude Execution Time Profiler
3    Copyright (C) 2010  Robert D. Cameron and Dan Lin
4    Version 0.4
5    Licensed to the general public under Academic Free License version 3.0
6
7Wall_Profiler provides a lightweight multiplatform execution time profiling
8utility based on processor cycle counters.  It uses a binary logarithmic
9histogram technique that is useful in both highlighting patterns of
10cycle time distributions as well as identifing outliers in timing events
11due to interruptions for operating system services.
12
13In essence, Wall profiler is designed to collect statistics over a number
14of repetitions of particular timed events.  Statistics are gathered in the
15form of a logarithmic histogram of cycle times for processing a fixed number
16of elements between calls to start_Wall_interval and end_Wall_interval. 
17For example, an interval may correspond to processing 1024 single-byte
18elements by a particular routine.
19
20A timer t is created and initialized by a call to t = init_Wall_timer(). 
21Given a timer t, start_Wall_interval(t) initiates an interval measurement
22which completes with end_Wall_interval(t, n), where n is the number of
23elements processed. 
24
25dump_Timer_Table(t) prints out a rudimentary histogram of the recorded
26intervals for a particular timer. 
27
28Although the basic concept of Wall_Profiler is architecture independent,
29processor-dependent routines for accessing time-stamp counters and
30determining the binary order of magnitude are included through external
31files.
32
33
34*/
35
36#ifndef WallTimer_H
37#define WallTimer_H
38
39#include <sys/time.h>
40#include "i386_timer.h"
41
42#define BIT_COUNT 64
43#define MAX_TIMER_ENTRIES (1<<18)
44#define TIMER_SCALE_FACTOR 1000
45
46#define timestamp_t uint64_t
47
48struct Timer_Table {
49  // current timing interval information
50  int timer_on;
51  int full;
52  struct timeval interval_start[MAX_TIMER_ENTRIES];
53  struct timeval interval_end[MAX_TIMER_ENTRIES];
54  unsigned int interval_elems[MAX_TIMER_ENTRIES]; 
55  unsigned int current_entry;
56};
57
58typedef struct Timer_Table Timer_Table;
59
60static inline Timer_Table * init_Wall_timer () {
61  Timer_Table * timer_table = (Timer_Table *) malloc(sizeof(Timer_Table));
62  if (!timer_table) {
63    printf("Couldn't initialize Wall timer.\n");
64    exit(-1);
65  }
66  timer_table -> current_entry = 0;
67  timer_table -> full = 0;
68  timer_table -> timer_on = 0;
69  return timer_table;
70}
71
72
73static inline void start_Wall_interval(Timer_Table * timer_table) {
74  timer_table->timer_on = 1;
75  gettimeofday(&timer_table->interval_start[timer_table->current_entry], NULL);
76}
77
78static inline void end_Wall_interval(Timer_Table * timer_table, unsigned int elems) {
79  if (timer_table->timer_on) {
80    gettimeofday(&timer_table->interval_end[timer_table->current_entry], NULL);
81    timer_table->interval_elems[timer_table->current_entry] = elems;
82    timer_table->current_entry++;
83    if(timer_table->current_entry >= MAX_TIMER_ENTRIES) {
84      timer_table->full=1;
85      timer_table->current_entry=0;
86    }
87    timer_table->timer_on = 0;
88  }
89  else
90        fprintf(stderr,"Time interval end without a start!\n"); 
91}
92
93
94
95static void dump_Timer_Table(Timer_Table * timer_table) {
96  // an array of counts and timings per binary order of magnitude
97  int Wall_count[BIT_COUNT];
98  unsigned int Wall_elems[BIT_COUNT]; 
99  timestamp_t Wall_total_time[BIT_COUNT];
100  int i, BOM, b;
101  int this_count;
102  int cum_count = 0;
103  unsigned int entry = 0;
104  unsigned int total_entries;
105  unsigned int this_elems = 0;
106  unsigned int cum_elems = 0;
107  timestamp_t this_time;
108  timestamp_t cum_time = 0ULL;
109  timestamp_t this_avg;
110  timestamp_t cum_avg;
111  timestamp_t accumulated_usec; 
112
113
114  for (b = 0; b < BIT_COUNT; b++) {
115        Wall_count[b] = 0;
116        Wall_elems[b] = 0;
117        Wall_total_time[b] = 0;
118  }
119
120
121  total_entries = timer_table->full ? MAX_TIMER_ENTRIES : timer_table->current_entry;
122  for(entry = 0; entry < total_entries; entry++){
123        accumulated_usec = 1000000 * (timer_table->interval_end[entry].tv_sec - 
124                                        (timer_table->interval_start[entry]).tv_sec) +
125                             (timer_table->interval_end[entry].tv_usec - timer_table->interval_start[entry].tv_usec);
126        if (accumulated_usec > 0ULL) {
127//        cout << "accumulated_usec =" << accumulated_usec << "; elems = " << timer_table->interval_elems[entry] << endl;
128            BOM = binary_order_of_magnitude(accumulated_usec*TIMER_SCALE_FACTOR/timer_table->interval_elems[entry]);
129            Wall_count[BOM]++;
130            Wall_elems[BOM] += timer_table->interval_elems[entry];
131            Wall_total_time[BOM] += accumulated_usec;
132        }
133  }
134 
135  printf("Binary Order of Magnitude Profile\n");
136  for (b = 0; b < BIT_COUNT; b++) {
137    this_count = Wall_count[b];
138    cum_count += this_count;
139    this_time = Wall_total_time[b];
140    cum_time += this_time;
141    this_elems = Wall_elems[b];
142    cum_elems += this_elems;
143    if (this_count == 0) this_avg = 0ULL;
144    else this_avg = (TIMER_SCALE_FACTOR*this_time)/(this_elems);
145    if (cum_count == 0) cum_avg = 0ULL;
146    else cum_avg = (TIMER_SCALE_FACTOR*cum_time)/(cum_elems);
147    if (this_count > 0) {  // Only report intervals with nonzero counts.
148      printf("BOM %i: %i ", b, this_count);
149      printf("(avg time: %i microsec/kElem) ", (int) this_avg);
150      printf("Cumulative: %i ", cum_count);
151      printf("(avg: %i microsec/kElem)\n", (int) cum_avg);
152    }
153  }           
154}
155
156static inline void destroy_Wall_timer(Timer_Table * timer_table) {
157        if(timer_table) {
158                free(timer_table);
159        }
160       
161}
162
163#endif
Note: See TracBrowser for help on using the repository browser.