org/objectweb/proactive/benchmarks/timit/util/HierarchicalTimer.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
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      * The ArrayList of HierarchicalTimers collected from others Workers ie
00066      * timed entities
00067      */
00068     private ArrayList<HierarchicalTimer> timersList;
00069 
00070     /* A 3 dim array of collected values */
00071     private int[][][] total; // MAX_DEPTH related
00072 
00073     /* The initial values */
00074     private long[] start;
00075 
00076     /* The current level used in case for hierarchy */
00077     protected int level;
00078 
00079     /* The parent counters array */
00080     protected int[] parent, parentStarted;
00081 
00082     /* The counter names */
00083     protected String[] counter_name;
00084 
00085     /* The number of counters */
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         // Initialization of deviation, average, min and max values
00425         // The value 0 is not used as init val of average and deviation
00426         // because it can be a timer value so -1d is used instead;
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         // Read all timers
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                             // Avoid init value addition
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                             // Same for average
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 }

Generated on Mon Jan 22 15:16:04 2007 for ProActive by  doxygen 1.5.1