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