view Histogram.c @ 14:1fbaedaac2c7

made defualt brch pure C (no VMS__malloc..)
author Me@portablequad
date Sat, 11 Feb 2012 19:19:06 -0800
parents 31a248920429
children 32489b8b763c
line source
1 /*
2 * Copyright 2010 OpenSourceStewardshipFoundation.org
3 * Licensed under GNU General Public License version 2
4 *
5 * Author: seanhalle@yahoo.com
6 *
7 */
8 #include <stdio.h>
9 #include "Histogram.h"
11 //External variables for saving of the histogram
12 //These have to be defined by to plugins in order to enable VMS to print this
13 //information to the histogram file
14 extern char __ProgrammName[]; //Defined in main.c
15 extern char __Scheduler[]; //Defined in VPThread_PluginFns.c
16 extern char __DataSet[255];
18 /*This Histogram Abstract Data Type has a number of bins plus a range of
19 * values that the bins span, both chosen at creation.
20 *
21 *One creates a Histogram instance using the makeHistogram function, then
22 * updates it with the addToHist function, and prints it out with the
23 * printHist function.
24 *
25 *Note, the bin width is an integer, so the end of the range is adjusted
26 * accordingly. Use the bin-width to calculate the bin boundaries.
27 */
30 Histogram *
31 makeHistogram( int32 numBins, int32 startOfRange, int32 endOfRange )
33 {
34 Histogram *hist;
35 int32 i;
38 hist = malloc( sizeof(Histogram) );
39 hist->bins = malloc( numBins * sizeof(int32) );
41 hist->numBins = numBins;
42 hist->binWidth = (endOfRange - startOfRange) / numBins;
43 hist->endOfRange = startOfRange + hist->binWidth * numBins;
44 hist->startOfRange = startOfRange;
46 for( i = 0; i < hist->numBins; i++ )
47 {
48 hist->bins[ i ] = 0;
49 }
51 hist->name = NULL;
52 return hist;
53 }
55 inline void
56 makeHist_helper( Histogram *hist, int32 numBins,
57 int32 startOfRange, int32 binWidth, char *nameCopy )
58 {
59 hist->numBins = numBins;
60 hist->binWidth = binWidth;
61 hist->endOfRange = startOfRange + hist->binWidth * numBins;
62 hist->startOfRange = startOfRange;
63 hist->name = nameCopy;
64 memset( hist->bins, 0, numBins * sizeof(int32) );
65 }
68 Histogram *
69 makeFixedBinHist( int32 numBins, int32 startOfRange, int32 binWidth,
70 char *name )
72 {
73 Histogram *hist;
75 hist = malloc( sizeof(Histogram) );
76 hist->bins = malloc( numBins * sizeof(int32) );
78 makeHist_helper( hist, numBins, startOfRange, binWidth,strDup(name));
80 return hist;
81 }
83 Histogram *
84 makeFixedBinHist( int32 numBins, int32 startOfRange, int32 binWidth,
85 char *name )
87 {
88 Histogram *hist;
90 hist = malloc( sizeof(Histogram) );
91 hist->bins = malloc( numBins * sizeof(int32) );
93 makeHist_helper( hist, numBins, startOfRange, binWidth, strdup(name));
95 return hist;
96 }
98 void inline
99 addToHist( int32 value, Histogram *hist )
100 {
101 int32 binIdx;
103 if( value < hist->startOfRange )
104 { binIdx = 0;
105 }
106 else if( value > hist->endOfRange )
107 { binIdx = hist->numBins - 1;
108 }
109 else
110 {
111 binIdx = (value - hist->startOfRange) / hist->binWidth;
112 }
114 hist->bins[ binIdx ] += 1;
115 }
117 void inline
118 subFromHist( int32 value, Histogram *hist )
119 {
120 int32 binIdx;
122 if( value < hist->startOfRange )
123 { binIdx = 0;
124 }
125 else if( value > hist->endOfRange )
126 { binIdx = hist->numBins - 1;
127 }
128 else
129 {
130 binIdx = (value - hist->startOfRange) / hist->binWidth;
131 }
133 hist->bins[ binIdx ] -= 1;
134 }
137 /*Inline because use with RDTSC in innermost code so need ultra-fast
138 */
139 void inline
140 addIntervalToHist( uint32 startIntvl, uint32 endIntvl, Histogram *hist )
141 {
142 int32 value;
144 value = endIntvl - startIntvl;
145 if( value < 0 || value > 10000000 ) return; //sanity check
146 addToHist( value, hist );
147 }
149 void inline
150 subIntervalFromHist( int32 startIntvl, int32 endIntvl, Histogram *hist )
151 {
152 int32 value;
154 value = endIntvl - startIntvl;
155 if( value < 0 || value > 10000000 ) return; //sanity check
156 subFromHist( value, hist );
157 }
159 void
160 saveHistToFile(Histogram *hist)
161 {
162 FILE *output;
163 int32 binIdx, binStart, binEnd, centerValue, width;
164 int32 maxHeight, i,n;
165 float32 total, total2, expectedValue1, expectedValue2;
167 if(hist == NULL || hist->name == NULL)
168 return;
170 //Calculate the average
171 //do all except the top bin
172 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
173 for( i = 0; i < hist->numBins -1; i++ )
174 {
175 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
176 total += hist->bins[ i ];
177 binStart = hist->startOfRange + hist->binWidth * i;
178 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
179 }
180 //copy and calc expected value minus the top bin
181 expectedValue2 = expectedValue1;
182 expectedValue2 /= total;
183 total2 = total;
184 //now do last iteration, to add the top bin
185 if(maxHeight < hist->bins[ i ])
186 maxHeight = hist->bins[ i ];
187 total += hist->bins[ i ];
188 binStart = hist->startOfRange + hist->binWidth * i;
189 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
191 expectedValue1 /= total;
196 //If a histogram directory does not exist, do not save to file.
197 //TODO change to argument
198 char filename[255];
199 for(n=0;n<255;n++)
200 {
201 sprintf(filename, "./histograms/%s.%d.dat", hist->name,n);
202 output = fopen(filename,"r");
203 if(output)
204 {
205 fclose(output);
206 }else{
207 break;
208 }
209 }
210 printf("Saving Hist to File: %s ...\n", filename);
211 output = fopen(filename,"w+");
212 if(output == NULL){
213 printf("[!]No histogram was saved. To save histograms create folder 'histograms'.\n");
214 return;
215 }
217 /*
218 * Write the header of the measurement file.
219 */
220 //--------------------------
221 //Build Environment
222 fprintf(output, "# >> Build Environment <<\n");
223 fprintf(output, "# Hardware Architecture: ");
224 #ifdef __x86_64
225 fprintf(output, "x86_64");
226 #endif //__x86_64
227 #ifdef __i386
228 fprintf(output, "x86");
229 #endif //__i386
230 fprintf(output, "\n");
231 fprintf(output, "# GCC VERSION: %d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
232 fprintf(output, "# Build Date: %s %s\n", __DATE__, __TIME__);
233 fprintf(output, "# Number of Cores: %d\n", NUM_CORES);
234 //--------------------------
236 //--------------------------
237 //VMS Plugins
238 fprintf(output, "#\n# >> VMS Plugins <<\n");
239 fprintf(output, "# Language : ");
240 #ifdef VPTHREAD
241 fprintf(output, "VPThread");
242 #endif
243 #ifdef VCILK
244 fprintf(output, "VCilk");
245 #endif
246 #ifdef SSR
247 fprintf(output, "SSR");
248 #endif
249 fprintf(output, "\n");
250 fprintf(output, "# Scheduler: %s\n", __Scheduler);
252 //--------------------------
253 //Application
254 fprintf(output, "#\n# >> Application <<\n");
255 fprintf(output, "# Name: %s\n", __ProgrammName);
256 fprintf(output, "# Data Set:\n%s\n",__DataSet);
258 //--------------------------
259 //Histogram
260 fprintf(output, "#\n# Histogram Name: %s\n", hist->name);
261 fprintf(output, "# Expected Values\n");
262 fprintf(output, "#\tnum samples: %d | expected value: %3.2f \n",
263 (int)total, expectedValue1 );
264 fprintf(output, "#\tminus top bin, num samples: %d | expected value: %3.2f \n",
265 (int)total2, expectedValue2 );
266 fprintf(output, "#\n# [Interval] [Center Value] [Count] [relative Count] [Width]\n");
268 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
269 {
270 binStart = hist->startOfRange + hist->binWidth * binIdx;
271 binEnd = binStart + hist->binWidth - 1;
272 centerValue = (binStart+binEnd)/2;
273 width = (binEnd-binStart)+1;
274 fprintf(output, "%d-%d\t%d\t%d\t%.4f\t%d\n", binStart, binEnd, centerValue,
275 hist->bins[ binIdx ],
276 hist->bins[ binIdx ]/total, width);
277 }
279 fclose(output);
280 fflush(stdout);
281 }
283 void
284 printHist( Histogram *hist )
285 {
286 int32 binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;
287 float32 total, total2, binPercent, expectedValue1, expectedValue2;
289 if( hist == NULL ) return;
291 //do all except the top bin
292 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
293 for( i = 0; i < hist->numBins -1; i++ )
294 {
295 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
296 total += hist->bins[ i ];
297 binStart = hist->startOfRange + hist->binWidth * i;
298 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
299 }
300 //copy and calc expected value minus the top bin
301 expectedValue2 = expectedValue1;
302 expectedValue2 /= total;
303 total2 = total;
304 //now do last iteration, to add the top bin
305 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
306 total += hist->bins[ i ];
307 binStart = hist->startOfRange + hist->binWidth * i;
308 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
310 expectedValue1 /= total;
312 printf( "histogram: " );
313 if( hist->name != NULL ) printf( "%s\n", hist->name );
314 else printf( "\n" );
315 printf( " num samples: %d | expected value: %3.2f \n",
316 (int)total, expectedValue1 );
317 printf( "minus top bin, num samples: %d | expected value: %3.2f \n",
318 (int)total2, expectedValue2 );
320 if(maxHeight < 60){
321 barValue = 1;
322 printf("Single Bar Value: %i\n", barValue);
323 }else{
324 barValue = maxHeight / 60; //60 spaces across page for tallest bin
325 printf("Single Bar Value: %0.3f\n", (float)maxHeight /60);
326 }
328 if( barValue == 0 ) { printf("error: bar val zero\n"); return; }
329 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
330 {
331 binStart = hist->startOfRange + hist->binWidth * binIdx;
332 binEnd = binStart + hist->binWidth - 1;
333 binPercent = 100 * hist->bins[ binIdx ] / total;
334 printf("bin range: %d - %d | %3.2f", binStart, binEnd, binPercent );
336 numBars = hist->bins[ binIdx ] / barValue;
337 //print one bin, height of bar is num dashes across page
338 for( i = 0; i < numBars; i++ )
339 {
340 printf("-");
341 }
342 printf("\n");
343 }
344 }
346 void
347 freeHist( Histogram *hist )
348 {
349 free( hist->bins );
350 free( hist->name );
351 free( hist );
352 }