view Histogram.c @ 16:f4d96eaf374a

updated for VMS name chgs from VMS__malloc to VMS_int__malloc
author Me@portablequad
date Sun, 12 Feb 2012 01:45:40 -0800
parents 32489b8b763c
children cd8275f62ee1 4d9af65ad3df
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 )
32 {
33 Histogram *hist;
34 int32 i;
37 hist = VMS_int__malloc( sizeof(Histogram) );
38 hist->bins = VMS_int__malloc( numBins * sizeof(int32) );
40 hist->numBins = numBins;
41 hist->binWidth = (endOfRange - startOfRange) / numBins;
42 hist->endOfRange = startOfRange + hist->binWidth * numBins;
43 hist->startOfRange = startOfRange;
45 for( i = 0; i < hist->numBins; i++ )
46 {
47 hist->bins[ i ] = 0;
48 }
50 hist->name = NULL;
51 return hist;
52 }
54 inline void
55 makeHist_helper( Histogram *hist, int32 numBins,
56 int32 startOfRange, int32 binWidth, char *nameCopy )
57 {
58 hist->numBins = numBins;
59 hist->binWidth = binWidth;
60 hist->endOfRange = startOfRange + hist->binWidth * numBins;
61 hist->startOfRange = startOfRange;
62 hist->name = nameCopy;
63 memset( hist->bins, 0, numBins * sizeof(int32) );
64 }
67 Histogram *
68 makeFixedBinHist( int32 numBins, int32 startOfRange, int32 binWidth,
69 char *name )
71 {
72 Histogram *hist;
74 hist = VMS_int__malloc( sizeof(Histogram) );
75 hist->bins = VMS_int__malloc( numBins * sizeof(int32) );
77 makeHist_helper( hist, numBins, startOfRange, binWidth,VMS_int__strDup(name));
79 return hist;
80 }
82 Histogram *
83 makeFixedBinHistExt( int32 numBins, int32 startOfRange, int32 binWidth,
84 char *name )
86 {
87 Histogram *hist;
89 hist = malloc( sizeof(Histogram) );
90 hist->bins = malloc( numBins * sizeof(int32) );
92 makeHist_helper( hist, numBins, startOfRange, binWidth, strdup(name));
94 return hist;
95 }
97 void inline
98 addToHist( int32 value, Histogram *hist )
99 {
100 int32 binIdx;
102 if( value < hist->startOfRange )
103 { binIdx = 0;
104 }
105 else if( value > hist->endOfRange )
106 { binIdx = hist->numBins - 1;
107 }
108 else
109 {
110 binIdx = (value - hist->startOfRange) / hist->binWidth;
111 }
113 hist->bins[ binIdx ] += 1;
114 }
116 void inline
117 subFromHist( int32 value, Histogram *hist )
118 {
119 int32 binIdx;
121 if( value < hist->startOfRange )
122 { binIdx = 0;
123 }
124 else if( value > hist->endOfRange )
125 { binIdx = hist->numBins - 1;
126 }
127 else
128 {
129 binIdx = (value - hist->startOfRange) / hist->binWidth;
130 }
132 hist->bins[ binIdx ] -= 1;
133 }
136 /*Inline because use with RDTSC in innermost code so need ultra-fast
137 */
138 void inline
139 addIntervalToHist( uint32 startIntvl, uint32 endIntvl, Histogram *hist )
140 {
141 int32 value;
143 value = endIntvl - startIntvl;
144 if( value < 0 || value > 10000000 ) return; //sanity check
145 addToHist( value, hist );
146 }
148 void inline
149 subIntervalFromHist( int32 startIntvl, int32 endIntvl, Histogram *hist )
150 {
151 int32 value;
153 value = endIntvl - startIntvl;
154 if( value < 0 || value > 10000000 ) return; //sanity check
155 subFromHist( value, hist );
156 }
158 void
159 saveHistToFile(Histogram *hist)
160 {
161 FILE *output;
162 int32 binIdx, binStart, binEnd, centerValue, width;
163 int32 maxHeight, i,n;
164 float32 total, total2, expectedValue1, expectedValue2;
166 if(hist == NULL || hist->name == NULL)
167 return;
169 //Calculate the average
170 //do all except the top bin
171 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
172 for( i = 0; i < hist->numBins -1; i++ )
173 {
174 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
175 total += hist->bins[ i ];
176 binStart = hist->startOfRange + hist->binWidth * i;
177 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
178 }
179 //copy and calc expected value minus the top bin
180 expectedValue2 = expectedValue1;
181 expectedValue2 /= total;
182 total2 = total;
183 //now do last iteration, to add the top bin
184 if(maxHeight < hist->bins[ i ])
185 maxHeight = hist->bins[ i ];
186 total += hist->bins[ i ];
187 binStart = hist->startOfRange + hist->binWidth * i;
188 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
190 expectedValue1 /= total;
195 //If a histogram directory does not exist, do not save to file.
196 //TODO change to argument
197 char filename[255];
198 for(n=0;n<255;n++)
199 {
200 sprintf(filename, "./histograms/%s.%d.dat", hist->name,n);
201 output = fopen(filename,"r");
202 if(output)
203 {
204 fclose(output);
205 }else{
206 break;
207 }
208 }
209 printf("Saving Hist to File: %s ...\n", filename);
210 output = fopen(filename,"w+");
211 if(output == NULL){
212 printf("[!]No histogram was saved. To save histograms create folder 'histograms'.\n");
213 return;
214 }
216 /*
217 * Write the header of the measurement file.
218 */
219 //--------------------------
220 //Build Environment
221 fprintf(output, "# >> Build Environment <<\n");
222 fprintf(output, "# Hardware Architecture: ");
223 #ifdef __x86_64
224 fprintf(output, "x86_64");
225 #endif //__x86_64
226 #ifdef __i386
227 fprintf(output, "x86");
228 #endif //__i386
229 fprintf(output, "\n");
230 fprintf(output, "# GCC VERSION: %d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
231 fprintf(output, "# Build Date: %s %s\n", __DATE__, __TIME__);
232 fprintf(output, "# Number of Cores: %d\n", NUM_CORES);
233 //--------------------------
235 //--------------------------
236 //VMS Plugins
237 fprintf(output, "#\n# >> VMS Plugins <<\n");
238 fprintf(output, "# Language : ");
239 #ifdef VPTHREAD
240 fprintf(output, "VPThread");
241 #endif
242 #ifdef VCILK
243 fprintf(output, "VCilk");
244 #endif
245 #ifdef SSR
246 fprintf(output, "SSR");
247 #endif
248 fprintf(output, "\n");
249 fprintf(output, "# Scheduler: %s\n", __Scheduler);
251 //--------------------------
252 //Application
253 fprintf(output, "#\n# >> Application <<\n");
254 fprintf(output, "# Name: %s\n", __ProgrammName);
255 fprintf(output, "# Data Set:\n%s\n",__DataSet);
257 //--------------------------
258 //Histogram
259 fprintf(output, "#\n# Histogram Name: %s\n", hist->name);
260 fprintf(output, "# Expected Values\n");
261 fprintf(output, "#\tnum samples: %d | expected value: %3.2f \n",
262 (int)total, expectedValue1 );
263 fprintf(output, "#\tminus top bin, num samples: %d | expected value: %3.2f \n",
264 (int)total2, expectedValue2 );
265 fprintf(output, "#\n# [Interval] [Center Value] [Count] [relative Count] [Width]\n");
267 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
268 {
269 binStart = hist->startOfRange + hist->binWidth * binIdx;
270 binEnd = binStart + hist->binWidth - 1;
271 centerValue = (binStart+binEnd)/2;
272 width = (binEnd-binStart)+1;
273 fprintf(output, "%d-%d\t%d\t%d\t%.4f\t%d\n", binStart, binEnd, centerValue,
274 hist->bins[ binIdx ],
275 hist->bins[ binIdx ]/total, width);
276 }
278 fclose(output);
279 fflush(stdout);
280 }
282 void
283 printHist( Histogram *hist )
284 {
285 int32 binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;
286 float32 total, total2, binPercent, expectedValue1, expectedValue2;
288 if( hist == NULL ) return;
290 //do all except the top bin
291 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
292 for( i = 0; i < hist->numBins -1; i++ )
293 {
294 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
295 total += hist->bins[ i ];
296 binStart = hist->startOfRange + hist->binWidth * i;
297 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
298 }
299 //copy and calc expected value minus the top bin
300 expectedValue2 = expectedValue1;
301 expectedValue2 /= total;
302 total2 = total;
303 //now do last iteration, to add the top bin
304 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
305 total += hist->bins[ i ];
306 binStart = hist->startOfRange + hist->binWidth * i;
307 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
309 expectedValue1 /= total;
311 printf( "histogram: " );
312 if( hist->name != NULL ) printf( "%s\n", hist->name );
313 else printf( "\n" );
314 printf( " num samples: %d | expected value: %3.2f \n",
315 (int)total, expectedValue1 );
316 printf( "minus top bin, num samples: %d | expected value: %3.2f \n",
317 (int)total2, expectedValue2 );
319 if(maxHeight < 60){
320 barValue = 1;
321 printf("Single Bar Value: %i\n", barValue);
322 }else{
323 barValue = maxHeight / 60; //60 spaces across page for tallest bin
324 printf("Single Bar Value: %0.3f\n", (float)maxHeight /60);
325 }
327 if( barValue == 0 ) { printf("error: bar val zero\n"); return; }
328 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
329 {
330 binStart = hist->startOfRange + hist->binWidth * binIdx;
331 binEnd = binStart + hist->binWidth - 1;
332 binPercent = 100 * hist->bins[ binIdx ] / total;
333 printf("bin range: %d - %d | %3.2f", binStart, binEnd, binPercent );
335 numBars = hist->bins[ binIdx ] / barValue;
336 //print one bin, height of bar is num dashes across page
337 for( i = 0; i < numBars; i++ )
338 {
339 printf("-");
340 }
341 printf("\n");
342 }
343 }
345 void
346 freeHist( Histogram *hist )
347 {
348 VMS_int__free( hist->bins );
349 VMS_int__free( hist->name );
350 VMS_int__free( hist );
351 }
352 void
353 freeHistExt( Histogram *hist )
354 {
355 free( hist->bins );
356 free( hist->name );
357 free( hist );
358 }