Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Histogram
view Histogram.c @ 13:2409ce192375
include statements adapted to the new folder structure
| author | hausers |
|---|---|
| date | Thu, 09 Feb 2012 15:53:03 +0100 |
| parents | 7a39408f9ea3 |
| children | 1fbaedaac2c7 |
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"
10 #include "../VMS.h"
11 #include "../vutilities.h"
12 #include "../vmalloc.h"
14 //External variables for saving of the histogram
15 //These have to be defined by to plugins in order to enable VMS to print this
16 //information to the histogram file
17 extern char __ProgrammName[]; //Defined in main.c
18 extern char __Scheduler[]; //Defined in VPThread_PluginFns.c
19 extern char __DataSet[255];
21 /*This Histogram Abstract Data Type has a number of bins plus a range of
22 * values that the bins span, both chosen at creation.
23 *
24 *One creates a Histogram instance using the makeHistogram function, then
25 * updates it with the addToHist function, and prints it out with the
26 * printHist function.
27 *
28 *Note, the bin width is an integer, so the end of the range is adjusted
29 * accordingly. Use the bin-width to calculate the bin boundaries.
30 */
33 Histogram *
34 makeHistogram( int32 numBins, int32 startOfRange, int32 endOfRange )
36 {
37 Histogram *hist;
38 int32 i;
41 hist = VMS__malloc( sizeof(Histogram) );
42 hist->bins = VMS__malloc( numBins * sizeof(int32) );
44 hist->numBins = numBins;
45 hist->binWidth = (endOfRange - startOfRange) / numBins;
46 hist->endOfRange = startOfRange + hist->binWidth * numBins;
47 hist->startOfRange = startOfRange;
49 for( i = 0; i < hist->numBins; i++ )
50 {
51 hist->bins[ i ] = 0;
52 }
54 hist->name = NULL;
55 return hist;
56 }
58 inline void
59 makeHist_helper( Histogram *hist, int32 numBins,
60 int32 startOfRange, int32 binWidth, char *nameCopy )
61 {
62 hist->numBins = numBins;
63 hist->binWidth = binWidth;
64 hist->endOfRange = startOfRange + hist->binWidth * numBins;
65 hist->startOfRange = startOfRange;
66 hist->name = nameCopy;
67 memset( hist->bins, 0, numBins * sizeof(int32) );
68 }
71 Histogram *
72 makeFixedBinHist( int32 numBins, int32 startOfRange, int32 binWidth,
73 char *name )
75 {
76 Histogram *hist;
78 hist = VMS__malloc( sizeof(Histogram) );
79 hist->bins = VMS__malloc( numBins * sizeof(int32) );
81 makeHist_helper( hist, numBins, startOfRange, binWidth,VMS__strDup(name));
83 return hist;
84 }
86 Histogram *
87 makeFixedBinHistExt( int32 numBins, int32 startOfRange, int32 binWidth,
88 char *name )
90 {
91 Histogram *hist;
93 hist = malloc( sizeof(Histogram) );
94 hist->bins = malloc( numBins * sizeof(int32) );
96 makeHist_helper( hist, numBins, startOfRange, binWidth, strdup(name));
98 return hist;
99 }
101 void inline
102 addToHist( int32 value, Histogram *hist )
103 {
104 int32 binIdx;
106 if( value < hist->startOfRange )
107 { binIdx = 0;
108 }
109 else if( value > hist->endOfRange )
110 { binIdx = hist->numBins - 1;
111 }
112 else
113 {
114 binIdx = (value - hist->startOfRange) / hist->binWidth;
115 }
117 hist->bins[ binIdx ] += 1;
118 }
120 void inline
121 subFromHist( int32 value, Histogram *hist )
122 {
123 int32 binIdx;
125 if( value < hist->startOfRange )
126 { binIdx = 0;
127 }
128 else if( value > hist->endOfRange )
129 { binIdx = hist->numBins - 1;
130 }
131 else
132 {
133 binIdx = (value - hist->startOfRange) / hist->binWidth;
134 }
136 hist->bins[ binIdx ] -= 1;
137 }
140 /*Inline because use with RDTSC in innermost code so need ultra-fast
141 */
142 void inline
143 addIntervalToHist( uint32 startIntvl, uint32 endIntvl, Histogram *hist )
144 {
145 int32 value;
147 value = endIntvl - startIntvl;
148 if( value < 0 || value > 10000000 ) return; //sanity check
149 addToHist( value, hist );
150 }
152 void inline
153 subIntervalFromHist( int32 startIntvl, int32 endIntvl, Histogram *hist )
154 {
155 int32 value;
157 value = endIntvl - startIntvl;
158 if( value < 0 || value > 10000000 ) return; //sanity check
159 subFromHist( value, hist );
160 }
162 void
163 saveHistToFile(Histogram *hist)
164 {
165 FILE *output;
166 int32 binIdx, binStart, binEnd, centerValue, width;
167 int32 maxHeight, i,n;
168 float32 total, total2, expectedValue1, expectedValue2;
170 if(hist == NULL || hist->name == NULL)
171 return;
173 //Calculate the average
174 //do all except the top bin
175 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
176 for( i = 0; i < hist->numBins -1; i++ )
177 {
178 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
179 total += hist->bins[ i ];
180 binStart = hist->startOfRange + hist->binWidth * i;
181 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
182 }
183 //copy and calc expected value minus the top bin
184 expectedValue2 = expectedValue1;
185 expectedValue2 /= total;
186 total2 = total;
187 //now do last iteration, to add the top bin
188 if(maxHeight < hist->bins[ i ])
189 maxHeight = hist->bins[ i ];
190 total += hist->bins[ i ];
191 binStart = hist->startOfRange + hist->binWidth * i;
192 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
194 expectedValue1 /= total;
199 //If a histogram directory does not exist, do not save to file.
200 //TODO change to argument
201 char filename[255];
202 for(n=0;n<255;n++)
203 {
204 sprintf(filename, "./histograms/%s.%d.dat", hist->name,n);
205 output = fopen(filename,"r");
206 if(output)
207 {
208 fclose(output);
209 }else{
210 break;
211 }
212 }
213 printf("Saving Hist to File: %s ...\n", filename);
214 output = fopen(filename,"w+");
215 if(output == NULL){
216 printf("[!]No histogram was saved. To save histograms create folder 'histograms'.\n");
217 return;
218 }
220 /*
221 * Write the header of the measurement file.
222 */
223 //--------------------------
224 //Build Environment
225 fprintf(output, "# >> Build Environment <<\n");
226 fprintf(output, "# Hardware Architecture: ");
227 #ifdef __x86_64
228 fprintf(output, "x86_64");
229 #endif //__x86_64
230 #ifdef __i386
231 fprintf(output, "x86");
232 #endif //__i386
233 fprintf(output, "\n");
234 fprintf(output, "# GCC VERSION: %d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
235 fprintf(output, "# Build Date: %s %s\n", __DATE__, __TIME__);
236 fprintf(output, "# Number of Cores: %d\n", NUM_CORES);
237 //--------------------------
239 //--------------------------
240 //VMS Plugins
241 fprintf(output, "#\n# >> VMS Plugins <<\n");
242 fprintf(output, "# Language : ");
243 #ifdef VPTHREAD
244 fprintf(output, "VPThread");
245 #endif
246 #ifdef VCILK
247 fprintf(output, "VCilk");
248 #endif
249 #ifdef SSR
250 fprintf(output, "SSR");
251 #endif
252 fprintf(output, "\n");
253 fprintf(output, "# Scheduler: %s\n", __Scheduler);
255 //--------------------------
256 //Application
257 fprintf(output, "#\n# >> Application <<\n");
258 fprintf(output, "# Name: %s\n", __ProgrammName);
259 fprintf(output, "# Data Set:\n%s\n",__DataSet);
261 //--------------------------
262 //Histogram
263 fprintf(output, "#\n# Histogram Name: %s\n", hist->name);
264 fprintf(output, "# Expected Values\n");
265 fprintf(output, "#\tnum samples: %d | expected value: %3.2f \n",
266 (int)total, expectedValue1 );
267 fprintf(output, "#\tminus top bin, num samples: %d | expected value: %3.2f \n",
268 (int)total2, expectedValue2 );
269 fprintf(output, "#\n# [Interval] [Center Value] [Count] [relative Count] [Width]\n");
271 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
272 {
273 binStart = hist->startOfRange + hist->binWidth * binIdx;
274 binEnd = binStart + hist->binWidth - 1;
275 centerValue = (binStart+binEnd)/2;
276 width = (binEnd-binStart)+1;
277 fprintf(output, "%d-%d\t%d\t%d\t%.4f\t%d\n", binStart, binEnd, centerValue,
278 hist->bins[ binIdx ],
279 hist->bins[ binIdx ]/total, width);
280 }
282 fclose(output);
283 fflush(stdout);
284 }
286 void
287 printHist( Histogram *hist )
288 {
289 int32 binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;
290 float32 total, total2, binPercent, expectedValue1, expectedValue2;
292 if( hist == NULL ) return;
294 //do all except the top bin
295 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
296 for( i = 0; i < hist->numBins -1; i++ )
297 {
298 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
299 total += hist->bins[ i ];
300 binStart = hist->startOfRange + hist->binWidth * i;
301 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
302 }
303 //copy and calc expected value minus the top bin
304 expectedValue2 = expectedValue1;
305 expectedValue2 /= total;
306 total2 = total;
307 //now do last iteration, to add the top bin
308 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
309 total += hist->bins[ i ];
310 binStart = hist->startOfRange + hist->binWidth * i;
311 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
313 expectedValue1 /= total;
315 printf( "histogram: " );
316 if( hist->name != NULL ) printf( "%s\n", hist->name );
317 else printf( "\n" );
318 printf( " num samples: %d | expected value: %3.2f \n",
319 (int)total, expectedValue1 );
320 printf( "minus top bin, num samples: %d | expected value: %3.2f \n",
321 (int)total2, expectedValue2 );
323 if(maxHeight < 60){
324 barValue = 1;
325 printf("Single Bar Value: %i\n", barValue);
326 }else{
327 barValue = maxHeight / 60; //60 spaces across page for tallest bin
328 printf("Single Bar Value: %0.3f\n", (float)maxHeight /60);
329 }
331 if( barValue == 0 ) { printf("error: bar val zero\n"); return; }
332 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
333 {
334 binStart = hist->startOfRange + hist->binWidth * binIdx;
335 binEnd = binStart + hist->binWidth - 1;
336 binPercent = 100 * hist->bins[ binIdx ] / total;
337 printf("bin range: %d - %d | %3.2f", binStart, binEnd, binPercent );
339 numBars = hist->bins[ binIdx ] / barValue;
340 //print one bin, height of bar is num dashes across page
341 for( i = 0; i < numBars; i++ )
342 {
343 printf("-");
344 }
345 printf("\n");
346 }
347 }
349 void
350 freeHist( Histogram *hist )
351 {
352 VMS__free( hist->bins );
353 VMS__free( hist->name );
354 VMS__free( hist );
355 }
356 void
357 freeHistExt( Histogram *hist )
358 {
359 free( hist->bins );
360 free( hist->name );
361 free( hist );
362 }
