my changes
[IRC.git] / Robust / src / Benchmarks / Scheduling / GC / NON_BAMBOO / GCBench / TestRunner.p
1 package GCBench;
2
3 //This is adapted from a benchmark written by John Ellis and Pete Kovac
4 //of Post Communications.
5 //It was modified by Hans Boehm of Silicon Graphics.
6
7 //This is no substitute for real applications.  No actual application
8 //is likely to behave in exactly this way.  However, this benchmark was
9 //designed to be more representative of real applications than other
10 //Java GC benchmarks of which we are aware.
11 //It attempts to model those properties of allocation requests that
12 //are important to current GC techniques.
13 //It is designed to be used either to obtain a single overall performance
14 //number, or to give a more detailed estimate of how collector
15 //performance varies with object lifetimes.  It prints the time
16 //required to allocate and collect balanced binary trees of various
17 //sizes.  Smaller trees result in shorter object lifetimes.  Each cycle
18 //allocates roughly the same amount of memory.
19 //Two data structures are kept around during the entire process, so
20 //that the measured performance is representative of applications
21 //that maintain some live in-memory data.  One of these is a tree
22 //containing many pointers.  The other is a large array containing
23 //double precision floating point numbers.  Both should be of comparable
24 //size.
25
26 //The results are only really meaningful together with a specification
27 //of how much memory was used.  It is possible to trade memory for
28 //better time performance.  This benchmark should be run in a 32 MB
29 //heap, though we don't currently know how to enforce that uniformly.
30
31 //Unlike the original Ellis and Kovac benchmark, we do not attempt
32 //measure pause times.  This facility should eventually be added back
33 //in.  There are several reasons for omitting it for now.  The original
34 //implementation depended on assumptions about the thread scheduler
35 //that don't hold uniformly.  The results really measure both the
36 //scheduler and GC.  Pause time measurements tend to not fit well with
37 //current benchmark suites.  As far as we know, none of the current
38 //commercial Java implementations seriously attempt to minimize GC pause
39 //times.
40
41 //Known deficiencies:
42 //- No way to check on memory use
43 //- No cyclic data structures
44 //- No attempt to measure variation with object size
45 //- Results are sensitive to locking cost, but we dont
46 //check for proper locking
47
48 public class TestRunner extends Thread {
49
50   public static final int kStretchTreeDepth = 16; // about 4Mb
51   public static final int kLongLivedTreeDepth = 14;  // about 1Mb
52   public static final int kArraySize  = 250000;  // about 1Mb
53   public static final int kMinTreeDepth = 4;
54   public static final int kMaxTreeDepth = 14;
55
56   // Nodes used by a tree of a given size
57   int TreeSize(int i) {
58     return ((1 << (i + 1)) - 1);
59   }
60
61   // Number of iterations to use for a given tree depth
62   int NumIters(int i) {
63     return 2 * TreeSize(kStretchTreeDepth) / TreeSize(i);
64   }
65
66   // Build tree top down, assigning to older objects. 
67   void Populate(int iDepth, Node thisNode) {
68     if (iDepth<=0) {
69       return;
70     } else {
71       iDepth--;
72       thisNode.left  = new Node();
73       thisNode.right = new Node();
74       Populate (iDepth, thisNode.left);
75       Populate (iDepth, thisNode.right);
76     }
77   }
78
79   // Build tree bottom-up
80   Node MakeTree(int iDepth) {
81     if (iDepth<=0) {
82       return new Node();
83     } else {
84       return new Node(MakeTree(iDepth-1),
85           MakeTree(iDepth-1));
86     }
87   }
88
89   void tc1(int depth) {
90     Node tempTree = new Node();
91     Populate(depth, tempTree);
92     tempTree = null;
93   }
94
95   void tc2(int depth) {
96     Node tempTree = MakeTree(depth);
97     tempTree = null;
98   }
99
100   void TimeConstruction(int depth) {
101     Node    root;
102     int   iNumIters = NumIters(depth);
103     Node  tempTree;
104
105     for (int i = 0; i < iNumIters; ++i) {
106       tc1(depth);
107     }
108     for (int i = 0; i < iNumIters; ++i) {
109       tc2(depth);
110     }
111   }
112
113   public void stretch() {
114     Node    root;
115     Node    longLivedTree;
116     Node    tempTree;
117
118     // Stretch the memory space quickly
119     tempTree = MakeTree(kStretchTreeDepth);
120     tempTree = null;
121   }
122
123   public void run() {
124     Node  root;
125     Node  longLivedTree;
126
127     // Stretch the memory space quickly
128     stretch();
129
130     // Create a long lived object
131     longLivedTree = new Node();
132     Populate(kLongLivedTreeDepth, longLivedTree);
133
134     // Create long-lived array, filling half of it
135     float array[] = new float[kArraySize];
136     for (int i = 0; i < kArraySize/2; ++i) {
137       array[i] = 1.0f/i;
138     }
139
140     for (int d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2) {
141       TimeConstruction(d);
142     }
143
144     if (longLivedTree == null || array[1000] != 1.0f/1000) {
145       System.out.println(0xa0);
146       System.out.println((int)(array[1000]*1000000));
147     }
148   }
149
150   public static void main(String[] args) {
151     int threadnum = THREADNUM;
152     System.setgcprofileflag();
153     for(int i = 0; i < threadnum; ++i) {
154       TestRunner tr = new TestRunner();
155       tr.start();
156     }
157   }
158 } // class JavaGC