Adding a new performance measurement mechanism, including its corresponding tracing...
authorIsaac Dooley <isaacdooley@hope.cs.uiuc.edu>
Wed, 13 Jan 2010 20:58:42 +0000 (14:58 -0600)
committerIsaac Dooley <isaacdooley@hope.cs.uiuc.edu>
Wed, 13 Jan 2010 20:58:42 +0000 (14:58 -0600)
src/ck-cp/controlPoints.C
src/ck-cp/controlPoints.ci
src/ck-cp/controlPoints.h
src/ck-perf/trace-controlPoints.C
src/ck-perf/trace-controlPoints.h

index e1d24461470358605fdbdda6b12f9ea2ce80cb59..fd8d079b702aa92513f9e262fad0491271d57cff 100644 (file)
@@ -9,11 +9,11 @@
 #include "cp_effects.h"
 
 
-/**
- *  \addtogroup ControlPointFramework
- *   @{
- *
- */
+//  A framework for tuning "control points" exposed by an application. Tuning decisions are based upon observed performance measurements.
+
+/** @defgroup ControlPointFramework Automatic Performance Tuning and Steering Framework  */
+/**  @{ */
 
 using namespace std;
 
@@ -72,9 +72,9 @@ void printTuningScheme(){
 
 
 
-/// A reduction type that combines idle time statistics (min/max/avg etc.)
+/// A reduction type that combines idle time measurements (min/sum/max etc.)
 CkReduction::reducerType idleTimeReductionType;
-/// A reducer that combines idle time statistics (min/max/avg etc.)
+/// A reducer that combines idle time measurements (min/sum/max etc.)
 CkReductionMsg *idleTimeReduction(int nMsg,CkReductionMsg **msgs){
   double ret[3];
   if(nMsg > 0){
@@ -93,12 +93,48 @@ CkReductionMsg *idleTimeReduction(int nMsg,CkReductionMsg **msgs){
   }  
   return CkReductionMsg::buildNew(3*sizeof(double),ret);   
 }
-/// An initcall that registers the idle time reducer idleTimeReduction()
-/*initproc*/ void registerIdleTimeReduction(void) {
-  idleTimeReductionType=CkReduction::addReducer(idleTimeReduction);
+
+
+
+/// A reduction type that combines idle, overhead, and memory measurements
+CkReduction::reducerType idleOverMemReductionType;
+/// A reducer that combines idle, overhead, and memory measurements
+CkReductionMsg *idleOverMemReduction(int nMsg,CkReductionMsg **msgs){
+  double ret[7];
+  if(nMsg > 0){
+    CkAssert(msgs[0]->getSize()==7*sizeof(double));
+    double *m=(double *)msgs[0]->getData();
+    ret[0]=m[0];
+    ret[1]=m[1];
+    ret[2]=m[2];
+    ret[3]=m[3];
+    ret[4]=m[4];
+    ret[5]=m[5];
+    ret[6]=m[6];
+  }
+  for (int i=1;i<nMsg;i++) {
+    CkAssert(msgs[i]->getSize()==7*sizeof(double));
+    double *m=(double *)msgs[i]->getData();
+    // idle time (min/sum/max)
+    ret[0]=min(ret[0],m[0]);
+    ret[1]+=m[1];
+    ret[2]=max(ret[2],m[2]);
+    // overhead time (min/sum/max)
+    ret[3]=min(ret[3],m[3]);
+    ret[4]+=m[4];
+    ret[5]=max(ret[5],m[5]);
+    // mem usage (max)
+    ret[6]=max(ret[6],m[6]);
+  }  
+  return CkReductionMsg::buildNew(3*sizeof(double),ret);   
 }
 
 
+/// Registers the control point framework's reduction handlers at startup on each PE
+/*initproc*/ void registerCPReductions(void) {
+  idleTimeReductionType=CkReduction::addReducer(idleTimeReduction);
+  idleOverMemReductionType=CkReduction::addReducer(idleOverMemReduction);
+}
 
 
 
@@ -644,6 +680,78 @@ controlPointManager::controlPointManager(){
 
 
 
+
+
+
+
+
+
+
+
+
+  /// Entry method called on all PEs to request CPU utilization statistics and memory usage
+  void controlPointManager::requestIdleOverMem(CkCallback cb){
+    const double i = localControlPointTracingInstance()->idleRatio();
+    const double o = localControlPointTracingInstance()->overheadRatio();
+    const double m = localControlPointTracingInstance()->memoryUsage();
+    
+    double data[3+3+1];
+
+    double *idle = data;
+    double *over = data+3;
+    double *mem = data+6;
+
+    idle[0] = i;
+    idle[1] = i;
+    idle[2] = i;
+
+    over[0] = o;
+    over[1] = o;
+    over[2] = o;
+
+    mem[0] = m;
+    
+    localControlPointTracingInstance()->resetIdleOverheadMem();
+
+    contribute(7*sizeof(double),idle,idleOverMemReductionType, cb);
+  }
+  
+  /// All processors reduce their memory usages in requestIdleTime() to this method
+  void controlPointManager::gatherIdleOverMem(CkReductionMsg *msg){
+    int size=msg->getSize() / sizeof(double);
+    CkAssert(size==7);
+    double *data=(double *) msg->getData();
+        
+    double *idle = data;
+    double *over = data+3;
+    double *mem = data+6;
+
+    instrumentedPhase* prevPhase = previousPhaseData();
+    if(prevPhase != NULL){
+      CkPrintf("Storing idle time measurements\n");
+      prevPhase->idleTime.min = idle[0];
+      prevPhase->idleTime.avg = idle[1]/CkNumPes();
+      prevPhase->idleTime.max = idle[2];
+      
+      prevPhase->memoryUsageMB = mem[0];
+      
+      
+      CkPrintf("Stored idle time min=%lf in prevPhase=%p\n", prevPhase->idleTime.min, prevPhase);
+    } else {
+      CkPrintf("There is no previous phase to store measurements\n");
+    }
+    
+    alreadyRequestedIdleOverMem = false;
+    checkForShutdown();
+    delete msg;
+  }
+
+
+
+
+
+
+
   void controlPointManager::checkForShutdown(){
     if( exitWhenReady && !alreadyRequestedMemoryUsage && !alreadyRequestedIdleTime && CkMyPe()==0){
       doExitNow();
index 0b8ba28a3c293d05ee5935091deb27ee17b38dc8..1439600c44adc810c33ebeb6af4c080be981aafd 100644 (file)
@@ -8,7 +8,7 @@ module ControlPoints {
   readonly bool shouldGatherUtilization;
 
 
-  initproc void registerIdleTimeReduction(void);       
+  initproc void registerCPReductions(void);    
 
 
  message controlPointMsg { 
index 449703393b83ff9b921c459118252031fdde4448..a705b9a79d283b69fb9433197d3bc45633a702d3 100644 (file)
@@ -546,6 +546,7 @@ public:
 
   bool alreadyRequestedMemoryUsage;
   bool alreadyRequestedIdleTime;
+  bool alreadyRequestedIdleOverMem;
 
   bool exitWhenReady;
 
@@ -588,13 +589,7 @@ public:
 
   /// An application uses this to register an instrumented timing for this phase
   void setTiming(double time);
-  
-  /// Entry method called on all PEs to request memory usage
-  void requestIdleTime(CkCallback cb);
-  
-  /// All processors reduce their memory usages in requestIdleTime() to this method
-  void gatherIdleTime(CkReductionMsg *msg);
-  
+
   /// Check to see if we are in the shutdown process, and handle it appropriately.
   void checkForShutdown();
 
@@ -604,13 +599,29 @@ public:
   // All outstanding operations have completed, so do the shutdown now. First write files to output, and then call CkExit().
   void doExitNow();
 
+
+
+
   /// Entry method called on all PEs to request memory usage
   void requestMemoryUsage(CkCallback cb);
-
   /// All processors reduce their memory usages to this method
   void gatherMemoryUsage(CkReductionMsg *msg);
 
 
+  /// Entry method called on all PEs to request memory usage
+  void requestIdleTime(CkCallback cb);
+  /// All processors reduce their memory usages in requestIdleTime() to this method
+  void gatherIdleTime(CkReductionMsg *msg);
+  
+
+  /// Entry method called on all PEs to request Idle, Overhead, and Memory measurements
+  void requestIdleOverMem(CkCallback cb);
+  /// All processors reduce their memory usages in requestIdleTime() to this method
+  void gatherIdleOverMem(CkReductionMsg *msg);
+  
+
+
+
   /// Inform the control point framework that a named control point affects the priorities of some array  
   void associatePriorityArray(const char *name, int groupIdx);
   
index f9a06b38fab80db8b0524deaeea36acd1f36dd35..d11db2051dde90a9630c89c80dedc6c319ef0364 100644 (file)
@@ -109,12 +109,22 @@ void TraceControlPoints::endExecute(void)
   double executionTime = CmiWallTimer() - lastBeginExecuteTime;
   totalEntryMethodTime += executionTime;
   
+  double m = (double)CmiMemoryUsage();
+  if(memUsage < m){
+    memUsage = m;
+  }
+
   //  CkPrintf("[%d] Previously executing Entry Method completes. lastbeginMessageSize=%d executionTime=%lf\n", CkMyPe(), lastbeginMessageSize, executionTime);
 }
 
 void TraceControlPoints::beginIdle(double curWallTime) {
   lastBeginIdle = CmiWallTimer();
   // CkPrintf("[%d] Scheduler has no useful user-work\n", CkMyPe());
+
+  double m = (double)CmiMemoryUsage();
+  if(memUsage < m){
+    memUsage = m;
+  }
 }
 
 void TraceControlPoints::endIdle(double curWallTime) {
@@ -138,6 +148,10 @@ void TraceControlPoints::endComputation(void)
 void TraceControlPoints::malloc(void *where, int size, void **stack, int stackSize)
 {
   // CkPrintf("[%d] Memory allocation of size %d occurred\n", CkMyPe(), size);
+  double m = (double)CmiMemoryUsage();
+  if(memUsage < m){
+    memUsage = m;
+  }
 }
 
 void TraceControlPoints::free(void *where, int size) {
@@ -172,6 +186,15 @@ void TraceControlPoints::resetTimings(){
   lastResetTime = CmiWallTimer();
 }
 
+void TraceControlPoints::resetIdleOverheadMem(){
+  totalIdleTime = 0.0;
+  totalEntryMethodTime = 0.0;
+  memUsage = 0;
+  lastResetTime = CmiWallTimer();
+}
+
+
+
 TraceControlPoints *localControlPointTracingInstance(){
   return CkpvAccess(_trace);
 }
index 6b07ac329574a4f0447eaf7cff19a95be7309fc3..9b43bdd9ecf9805837ff11c7d6e08d5ac67bf945 100644 (file)
@@ -41,6 +41,11 @@ class TraceControlPoints : public Trace {
   /** The time we last rest the idle/entry totals */
   double lastResetTime;
 
+  /** The highest seen memory usage */
+  double memUsage;
+
+  
+
  public:
   TraceControlPoints(char **argv);
   
@@ -87,19 +92,32 @@ class TraceControlPoints : public Trace {
   void traceClose();
 
 
-
-
   // ==================================================================
   // The following methods are not required for a tracing module
 
   /** reset the idle time and entry method execution time accumulators */
   void resetTimings();
 
-  /** What fraction of the time is spent idle */
+  /** Reset the idle, overhead, and memory measurements */
+  void resetIdleOverheadMem();
+
+  /** Fraction of the time spent idle */
   double idleRatio(){
     return (totalIdleTime) / (CmiWallTimer() - lastResetTime);
   }
 
+  /** Fraction of time spent as overhead */
+  double overheadRatio(){
+    return 0.0;
+  }
+
+  /** Highest memory usage value we've seen since last time */
+  double memoryUsage(){
+    return 0.0;
+  }
+
+
+
 };