source: u8u16/trunk/Profiling/BOM_Profiler.h @ 5877

Last change on this file since 5877 was 5877, checked in by cameron, 15 months ago

Adding old u8u16 for Teradata

File size: 5.0 KB
Line 
1/*
2    BOM_Profiler.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
7BOM_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, BOM 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_BOM_interval and end_BOM_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_BOM_timer(). 
21Given a timer t, start_BOM_interval(t) initiates an interval measurement
22which completes with end_BOM_interval(t, n), where n is the number of
23elements processed. 
24
25dump_BOM_table(t) prints out a rudimentary histogram of the recorded
26intervals for a particular timer. 
27
28Although the basic concept of BOM_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 BOM_Profiler_H
37#define BOM_Profiler_H
38
39
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
46struct BOM_Table {
47  // current timing interval information
48  int timer_on;
49  int full;
50  timestamp_t interval_start[MAX_TIMER_ENTRIES];
51  timestamp_t interval_end[MAX_TIMER_ENTRIES];
52  unsigned int interval_elems[MAX_TIMER_ENTRIES]; 
53  unsigned int current_entry;
54};
55
56typedef struct BOM_Table BOM_Table;
57
58BOM_Table * init_BOM_timer () {
59  BOM_Table * timer_table = (BOM_Table *) malloc(sizeof(BOM_Table));
60  if (!timer_table) {
61    printf("Couldn't initialize BOM timer.\n");
62    exit(-1);
63  }
64  timer_table -> current_entry = 0;
65  timer_table -> full = 0;
66  timer_table -> timer_on = 0;
67  return timer_table;
68}
69
70
71static inline void start_BOM_interval(BOM_Table * timer_table) {
72  timer_table->timer_on = 1;
73  timer_table->interval_start[timer_table->current_entry] = read_cycle_counter();
74}
75
76static inline void end_BOM_interval(BOM_Table * timer_table, unsigned int elems) {
77  if (timer_table->timer_on) {
78    timer_table->interval_end[timer_table->current_entry] = read_cycle_counter();
79    timer_table->interval_elems[timer_table->current_entry] = elems;
80    timer_table->current_entry++;
81    if(timer_table->current_entry >= MAX_TIMER_ENTRIES) {
82      timer_table->full=1;
83      timer_table->current_entry=0;
84    }
85    timer_table->timer_on = 0;
86  }
87  else
88        fprintf(stderr,"Time interval end without a start!\n"); 
89}
90
91void dump_BOM_table(BOM_Table * timer_table) {
92  // an array of counts and timings per binary order of magnitude
93  int BOM_count[BIT_COUNT];
94  unsigned int BOM_elems[BIT_COUNT]; 
95  timestamp_t BOM_total_time[BIT_COUNT];
96
97  int BOM, b;
98  int this_count;
99  int cum_count = 0;
100  unsigned int entry = 0;
101  unsigned int total_entries;
102  unsigned int this_elems = 0;
103  unsigned int cum_elems = 0;
104  timestamp_t this_time;
105  timestamp_t cum_time = 0ULL;
106  timestamp_t this_avg;
107  timestamp_t cum_avg;
108  timestamp_t accumulated_cycles; 
109
110  for (b = 0; b < BIT_COUNT; b++) {
111        BOM_count[b] = 0;
112        BOM_elems[b] = 0;
113        BOM_total_time[b] = 0;
114  }
115
116
117  total_entries = timer_table->full ? MAX_TIMER_ENTRIES : timer_table->current_entry;
118  for(entry = 0; entry < total_entries; entry++){
119        accumulated_cycles = timer_table->interval_end[entry] - timer_table->interval_start[entry];
120        if (accumulated_cycles > 0ULL) {
121            BOM = binary_order_of_magnitude(accumulated_cycles*TIMER_SCALE_FACTOR/timer_table->interval_elems[entry]);
122            BOM_count[BOM]++;
123            BOM_elems[BOM] += timer_table->interval_elems[entry];
124            BOM_total_time[BOM] += accumulated_cycles;
125        }
126  }
127 
128  printf("Binary Order of Magnitude Profile\n");
129  for (b = 0; b < BIT_COUNT; b++) {
130    this_count = BOM_count[b];
131    cum_count += this_count;
132    this_time = BOM_total_time[b];
133    cum_time += this_time;
134    this_elems = BOM_elems[b];
135    cum_elems += this_elems;
136    if (this_count == 0) this_avg = 0ULL;
137    else this_avg = (TIMER_SCALE_FACTOR*this_time)/(this_elems);
138    if (cum_count == 0) cum_avg = 0ULL;
139    else cum_avg = (TIMER_SCALE_FACTOR*cum_time)/(cum_elems);
140    if (this_count > 0) {  // Only report intervals with nonzero counts.
141      printf("BOM %i: %i ", b, this_count);
142      printf("(avg time: %i %s/kElem) ", (int) this_avg, cycle_counter_units);
143      printf("Cumulative: %i ", cum_count);
144      printf("(avg: %i %s/kElem)\n", (int) cum_avg, cycle_counter_units);
145    }
146  }           
147}
148#endif
Note: See TracBrowser for help on using the repository browser.