File: measureAspect.ah

package info (click to toggle)
aspectc%2B%2B 1.0pre4~svn.20090918-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 117,308 kB
  • ctags: 410,601
  • sloc: cpp: 1,883,007; ansic: 17,279; sh: 2,190; makefile: 1,088
file content (127 lines) | stat: -rw-r--r-- 3,724 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * measureAspect.ah
 * 
 * measure the runtime of target 
 */
#ifndef __MEASURE_ASPECT
#define __MEASURE_ASPECT
 
#include <algorithm>  // for std::sort
#include <fstream>
#include <sched.h>
#include <cstdio>

#include "doMeasurement.h"
#include "ArgumentSizeCalculator.h"
#include "SaveStack.h"

#define RUNS 20
#define SUMS 500
#define COUNTSKIP 5

void *frameAddress;
void *stackBeforeAction;

static int weirdCount;
static double average;
static cycle_t calibration;
static AC::Action nullAction;
      
aspect measure {
    // returns average, stores summed up results to buf of length len
    void __attribute__ ((noinline)) runTests(AC::Action &action, cycle_t *buf, unsigned len, cycle_t calibration = 0) {
       register unsigned i,j;
       double avg = 0;
       weirdCount = 0;
       average = 0;
       for(i = 0; i < len; i++) {      
         buf[i] = 0;

	// Accumulate RUNS runs, and calcualate mean
	 j = RUNS;
	 while(j--) {
           cycle_t result = doMeasurement(action);
           buf[i]  += result;
         }
         buf[i] /= RUNS;

         if (calibration > buf[i]) { // something weird happened
            buf[i] = 0;
	    weirdCount++;
         } else {
            buf[i] -= calibration;
         }

         avg += buf[i];
       }
       
       average = avg / (double)len;
    }
    
    pointcut virtual measureTarget () = 0; 
    advice call(measureTarget()) : order("measure", !"measure");        
	advice call(measureTarget()) : around() {       
       cycle_t runtimes[SUMS];
       register unsigned i = COUNTSKIP;
       ptrdiff_t overhead;
       std::ofstream out("out.txt", std::ios_base::app);

       if(sched_yield()) 
	 perror("doMeasurement");
       
       while(i--)
          doMeasurement(tjp->action()); // warm up caches
   
       size_t param_size = ArgumentSizeCalculator<JoinPoint>::RES;
       nullAction._wrapper = dispatch<JoinPoint, JoinPoint::ARGS>::doit;
       
       // do calibration
       runTests(nullAction, runtimes, SUMS);
       std::sort(runtimes, runtimes + SUMS);
       calibration = runtimes[SUMS/2];

#ifdef DEBUG      
       out << "\n results of calibration runs:\n";
       for (i = 0; i < SUMS; i++) 
          out << runtimes[i] << ", ";   
#endif
      
       // Expected overhead of measureAspect:
       // Action Object, Arguments, Stackalignment
       overhead = (ptrdiff_t)stackBeforeAction - (ptrdiff_t)frameAddress;

//       calibration = 0;      //  disable calibration
       frameAddress = 0; // reset frameAddress
       runTests(tjp->action(), runtimes, SUMS, calibration);


       // sort the array for median processing
       std::sort(runtimes, runtimes + SUMS);
 
       out << "\nMeasure times of target: " << tjp->signature() << "\n";              
       out << "\n Calibration took (in cycles): " << calibration;       
       out << "\n Average runtime: " << average;
       out << "\n Median is " << runtimes[SUMS/2];
       out << "\n esp overhead is " << overhead;
       out << "\n Number of arguments is: " << JoinPoint::ARGS;
       out << "\n Total Size of arguments: " << param_size;
       out << "\n Number of runs with calibration bigger than run: " << weirdCount;
       out << "\n Total runs of target: " << SUMS;

       if (frameAddress) {
          ptrdiff_t stackUsed = 
            (ptrdiff_t)stackBeforeAction - (ptrdiff_t)frameAddress - overhead;
          out << "\n Stack used: " << stackUsed << std::endl;
       } else {
          out << "\n Callee did not set used stack" << std::endl;
       }   
#ifdef DEBUG      
       out << "\n runtimes are: ";
       for (i = 0; i < SUMS; i++) 
          out << runtimes[i] << ", ";   
#endif
       out.close();
    }
};

#endif