00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.benchmarks.timit.util;
00032
00033 import java.io.Serializable;
00034 import java.util.ArrayList;
00035 import java.util.Arrays;
00036 import java.util.Iterator;
00037
00053 public class HierarchicalTimer implements Serializable {
00054
00058 private static final long serialVersionUID = -6579163067813117881L;
00059
00060 public static final int MAX_ENABLED_COUNTERS = 20;
00061
00062 private static final int MAX_DEPTH = 3;
00063
00064
00065
00066
00067
00068 private ArrayList<HierarchicalTimer> timersList;
00069
00070
00071 private int[][][] total;
00072
00073
00074 private long[] start;
00075
00076
00077 protected int level;
00078
00079
00080 protected int[] parent, parentStarted;
00081
00082
00083 protected String[] counter_name;
00084
00085
00086 private int nbCounters;
00087
00092 public HierarchicalTimer() {
00093 }
00094
00103 public void activateCounters(TimerCounter[] counters, TimItReductor tr) {
00104 this.nbCounters = counters.length;
00105
00106 if (this.nbCounters > HierarchicalTimer.MAX_ENABLED_COUNTERS) {
00107 throw new RuntimeException("Too many Counters to create. Max is "
00108 + HierarchicalTimer.MAX_ENABLED_COUNTERS);
00109 }
00110 this.total = new int[this.nbCounters][this.nbCounters][this.nbCounters];
00111 this.start = new long[HierarchicalTimer.MAX_DEPTH];
00112 this.parent = new int[HierarchicalTimer.MAX_DEPTH];
00113 this.parentStarted = new int[HierarchicalTimer.MAX_DEPTH];
00114 this.counter_name = new String[this.nbCounters];
00115 this.resetTimer();
00116 for (int i = 0; i < this.nbCounters; i++) {
00117 counters[i].setId(i);
00118 counters[i].setTimer(this);
00119 this.counter_name[i] = counters[i].getName();
00120 if (counters[i].isMigratable()) {
00121 ((MigratableCounter) (counters[i])).setClock(tr);
00122 }
00123 }
00124 }
00125
00129 public void resetTimer() {
00130 int i, j, k;
00131 for (i = 0; i < this.nbCounters; i++) {
00132 for (j = 0; j < this.nbCounters; j++) {
00133 for (k = 0; k < this.nbCounters; k++) {
00134 this.total[i][j][k] = -1;
00135 }
00136 }
00137 }
00138 Arrays.fill(this.parent, -1);
00139 this.level = -1;
00140 }
00141
00148 public void resetCounter(int n) {
00149 for (int i = 0; i < this.nbCounters; i++) {
00150 for (int j = 0; j < this.nbCounters; j++) {
00151 this.total[i][j][n] = -1;
00152 }
00153 }
00154 }
00155
00162 public void addInstance(HierarchicalTimer t) {
00163 if (this.timersList == null) {
00164 this.timersList = new ArrayList<HierarchicalTimer>();
00165 }
00166 this.timersList.add(t);
00167 }
00168
00174 public int getNbCounter() {
00175 return this.nbCounters;
00176 }
00177
00185 public String getCounterName(int n) {
00186 return this.counter_name[n];
00187 }
00188
00196 public boolean isStarted(int n) {
00197 return this.parent[0] == n || this.parent[1] == n
00198 || this.parent[2] == n;
00199 }
00200
00207 public void start(int n) {
00208 this.parent[++this.level] = n;
00209 this.start[this.level] = HierarchicalTimer.getCtm();
00210 }
00211
00212 public void startAsync(int n) {
00213 this.start(n);
00214 switch (this.level) {
00215 case 0:
00216 this.parentStarted[0] = this.parent[0];
00217 this.parentStarted[1] = this.parent[0];
00218 this.parentStarted[2] = this.parent[0];
00219 break;
00220 case 1:
00221 this.parentStarted[0] = this.parent[0];
00222 this.parentStarted[1] = this.parent[1];
00223 this.parentStarted[2] = this.parent[1];
00224 break;
00225 case 2:
00226 case 3:
00227 this.parentStarted[0] = this.parent[0];
00228 this.parentStarted[1] = this.parent[1];
00229 this.parentStarted[2] = this.parent[2];
00230 break;
00231 }
00232 }
00233
00240 public void stop(int n) {
00241 switch (this.level) {
00242 case 0:
00243 if (this.total[this.parent[0]][this.parent[0]][this.parent[0]] < 0) {
00244 this.total[this.parent[0]][this.parent[0]][this.parent[0]] = 1;
00245 }
00246 this.total[this.parent[0]][this.parent[0]][this.parent[0]] += HierarchicalTimer
00247 .getCtm()
00248 - this.start[this.level];
00249 break;
00250 case 1:
00251 if (this.total[this.parent[0]][this.parent[1]][this.parent[1]] < 0) {
00252 this.total[this.parent[0]][this.parent[1]][this.parent[1]] = 1;
00253 }
00254 this.total[this.parent[0]][this.parent[1]][this.parent[1]] += HierarchicalTimer
00255 .getCtm()
00256 - this.start[this.level];
00257 break;
00258 case 2:
00259 case 3:
00260 if (this.total[this.parent[0]][this.parent[1]][this.parent[2]] < 0) {
00261 this.total[this.parent[0]][this.parent[1]][this.parent[2]] = 1;
00262 }
00263 this.total[this.parent[0]][this.parent[1]][this.parent[2]] += HierarchicalTimer
00264 .getCtm()
00265 - this.start[this.level];
00266 }
00267 this.level--;
00268 }
00269
00270 public void stopAsync(int n) {
00271 if (this.total[this.parent[0]][this.parent[1]][this.parent[2]] < 0) {
00272 this.total[this.parent[0]][this.parent[1]][this.parent[2]] = 1;
00273 }
00274 this.total[this.parentStarted[0]][this.parentStarted[1]][this.parentStarted[2]] += HierarchicalTimer
00275 .getCtm()
00276 - this.start[this.level];
00277 this.level--;
00278 }
00279
00280 public void setValue(int n, int time) {
00281 this.parent[++this.level] = n;
00282 switch (this.level) {
00283 case 0:
00284 this.total[this.parent[0]][this.parent[0]][this.parent[0]] = time;
00285 break;
00286 case 1:
00287 this.total[this.parent[0]][this.parent[0]][this.parent[0]] -= this.total[this.parent[0]][this.parent[1]][this.parent[1]];
00288
00289 this.total[this.parent[0]][this.parent[1]][this.parent[1]] = time;
00290
00291 this.total[this.parent[0]][this.parent[0]][this.parent[0]] += time;
00292 break;
00293 case 2:
00294 case 3:
00295 this.total[this.parent[0]][this.parent[0]][this.parent[0]] -= this.total[this.parent[0]][this.parent[1]][this.parent[2]];
00296 this.total[this.parent[0]][this.parent[1]][this.parent[1]] -= this.total[this.parent[0]][this.parent[1]][this.parent[2]];
00297
00298 this.total[this.parent[0]][this.parent[1]][this.parent[2]] = time;
00299
00300 this.total[this.parent[0]][this.parent[0]][this.parent[0]] += time;
00301 this.total[this.parent[0]][this.parent[1]][this.parent[1]] += time;
00302 }
00303 this.level--;
00304 }
00305
00306 public void addValue(int n, int time) {
00307 this.parent[++this.level] = n;
00308 switch (this.level) {
00309 case 0:
00310 this.total[this.parent[0]][this.parent[0]][this.parent[0]] += time;
00311 break;
00312 case 1:
00313 this.total[this.parent[0]][this.parent[1]][this.parent[1]] += time;
00314 this.total[this.parent[0]][this.parent[0]][this.parent[0]] += time;
00315 break;
00316 case 2:
00317 case 3:
00318 this.total[this.parent[0]][this.parent[1]][this.parent[2]] += time;
00319 this.total[this.parent[0]][this.parent[0]][this.parent[0]] += time;
00320 this.total[this.parent[0]][this.parent[1]][this.parent[1]] += time;
00321 }
00322 this.level--;
00323 }
00324
00328 public int readTimer(int i, int j, int k) {
00329 return this.total[i][j][k];
00330 }
00331
00339 public int getElapsedTime(int n) {
00340 return (int) (HierarchicalTimer.getCtm() - this.start[this.level]);
00341 }
00342
00350 public int getHierarchicalTime(int n) {
00351 switch (this.level) {
00352 case 0:
00353 return this.total[this.parent[0]][this.parent[0]][this.parent[0]]
00354 + this.getElapsedTime(n);
00355 case 1:
00356 return this.total[this.parent[0]][this.parent[1]][this.parent[1]]
00357 + this.getElapsedTime(n);
00358 case 2:
00359 case 3:
00360 return this.total[this.parent[0]][this.parent[1]][this.parent[2]]
00361 + this.getElapsedTime(n);
00362 default:
00363 return 0;
00364 }
00365 }
00366
00375 public int getTotalTime(int n) {
00376 int value = 0;
00377 for (int[][] element : this.total) {
00378 for (int j = 0; j < this.total.length; j++) {
00379 value += element[j][n];
00380 }
00381 }
00382 return value;
00383 }
00384
00389 public String toString() {
00390 String result = "";
00391 int i, j, k;
00392 for (i = 0; i < this.total.length; i++) {
00393 for (j = 0; j < this.total.length; j++) {
00394 for (k = 0; k < this.total.length; k++) {
00395 if (this.total[i][j][k] != -1) {
00396 result += this.counter_name[i] + " -> "
00397 + this.counter_name[j] + " -> "
00398 + this.counter_name[k] + "\t = "
00399 + this.total[i][j][k] + " ms\n";
00400 }
00401 }
00402 }
00403 }
00404 return result;
00405 }
00406
00412 public HierarchicalTimerStatistics getStats() {
00413
00414 double[][][] deviation = new double[this.nbCounters][this.nbCounters][this.nbCounters];
00415 double[][][] average = new double[this.nbCounters][this.nbCounters][this.nbCounters];
00416 double[][][] min = new double[this.nbCounters][this.nbCounters][this.nbCounters];
00417 double[][][] max = new double[this.nbCounters][this.nbCounters][this.nbCounters];
00418 int[][][] t;
00419
00420 Iterator<HierarchicalTimer> it = this.timersList.iterator();
00421
00422 int i, j, k;
00423
00424
00425
00426
00427 for (i = 0; i < this.nbCounters; i++) {
00428 for (j = 0; j < this.nbCounters; j++) {
00429 for (k = 0; k < this.nbCounters; k++) {
00430 deviation[i][j][k] = -1d;
00431 average[i][j][k] = -1d;
00432 if (this.total[i][j][k] != -1) {
00433 min[i][j][k] = Double.MAX_VALUE;
00434 max[i][j][k] = Double.MIN_VALUE;
00435 } else {
00436 min[i][j][k] = -1d;
00437 max[i][j][k] = -1d;
00438 }
00439 }
00440 }
00441 }
00442
00443 HierarchicalTimer timer;
00444 double tempValue;
00445 int groupSize = 0;
00446
00447
00448 while (it.hasNext()) {
00449 groupSize++;
00450 timer = (it.next());
00451
00452 t = timer.total;
00453
00454 for (i = 0; i < this.nbCounters; i++) {
00455 for (j = 0; j < this.nbCounters; j++) {
00456 for (k = 0; k < this.nbCounters; k++) {
00457 if (t[i][j][k] != -1) {
00458
00459 tempValue = t[i][j][k] / 1000.0;
00460
00461 if (min[i][j][k] > tempValue) {
00462 min[i][j][k] = tempValue;
00463 }
00464 if (max[i][j][k] < tempValue) {
00465 max[i][j][k] = tempValue;
00466 }
00467
00468
00469 if (deviation[i][j][k] == -1d) {
00470 deviation[i][j][k] = tempValue * tempValue;
00471 } else {
00472 deviation[i][j][k] += tempValue * tempValue;
00473 }
00474
00475 if (average[i][j][k] == -1d) {
00476 average[i][j][k] = tempValue;
00477 } else {
00478 average[i][j][k] += tempValue;
00479 }
00480 }
00481 }
00482 }
00483 }
00484 }
00485
00486 for (i = 0; i < this.nbCounters; i++) {
00487 for (j = 0; j < this.nbCounters; j++) {
00488 for (k = 0; k < this.nbCounters; k++) {
00489 if (average[i][j][k] != -1d && deviation[i][j][k] != -1d) {
00490 average[i][j][k] /= groupSize;
00491 tempValue = average[i][j][k] * average[i][j][k];
00492 deviation[i][j][k] = Math.sqrt(deviation[i][j][k]
00493 / groupSize - tempValue);
00494 }
00495 }
00496 }
00497 }
00498 return new HierarchicalTimerStatistics(this.counter_name, deviation,
00499 average, min, max, this.parent, this.nbCounters);
00500 }
00501
00513 public static void printArray(double[][][] array, String[] counterName,
00514 int n) {
00515 String result = "";
00516 int i, j, k;
00517 for (i = 0; i < n; i++) {
00518 for (j = 0; j < n; j++) {
00519 for (k = 0; k < n; k++) {
00520 if (array[i][j][k] != -1d) {
00521 result += counterName[i] + " -> " + counterName[j]
00522 + " -> " + counterName[k] + "\t = "
00523 + array[i][j][k] + " s\n";
00524 }
00525 }
00526 }
00527 }
00528 System.out.println(result);
00529 }
00530
00535 protected static final long getCtm() {
00536 return System.currentTimeMillis();
00537 }
00538 }