00001 00002 #include "pose.h" 00003 00005 void adapt5::Step() 00006 { 00007 Event *ev; 00008 POSE_TimeType lastGVT = localPVT->getGVT(); 00009 POSE_TimeType maxTimeLeash, offset; 00010 double critStart; 00011 00012 rbFlag = 0; 00013 if (!parent->cancels.IsEmpty()) CancelUnexecutedEvents(); 00014 if (eq->RBevent) Rollback(); 00015 if (!parent->cancels.IsEmpty()) CancelEvents(); 00016 parent->Status(); 00017 00018 /* 00019 if (rbFlag) { // adjust leash according to rollback 00020 timeLeash = avgRBoffset; 00021 } 00022 else if (timeLeash < theMaxLeash) { // adjust according to state 00023 if (eq->currentPtr->timestamp > POSE_UnsetTS) { // adjust to next event 00024 if (eq->currentPtr->timestamp - lastGVT > timeLeash) 00025 timeLeash == eq->currentPtr->timestamp - lastGVT; 00026 // else leave it alone 00027 } 00028 // no next event; leave it alone 00029 } 00030 // Put leash back into reasonable bounds 00031 if (timeLeash > theMaxLeash) { 00032 timeLeash = theMaxLeash; 00033 } 00034 else if (timeLeash < 0) timeLeash = 0; 00035 */ 00036 00037 00038 /* 00039 int i = timeLeash >> 6; 00040 if (i > 1) { 00041 if (rbFlag) { 00042 timeLeash -= i; 00043 } else { 00044 timeLeash += i; 00045 } 00046 } else { 00047 if (rbFlag) { 00048 timeLeash--; 00049 } else { 00050 timeLeash++; 00051 } 00052 } 00053 00054 if (timeLeash <= 0) { 00055 timeLeash = 10; 00056 } 00057 */ 00058 /* 00059 if (rbFlag) { 00060 timeLeash = timeLeash >> 1; 00061 } else { 00062 timeLeash++; 00063 } 00064 */ 00065 00066 // other possibilities: 00067 // -run for a number of events with a fixed timeleash, then analyze 00068 // and adjust 00069 // -simply use recentAvgEventSparsity * avgEventsPerRB 00070 // -add code that looks at the number of RBs this poser is responsible 00071 // for and don't punish it if it doesn't have a lot 00072 00073 ev = eq->currentPtr; 00074 00075 if (parent->basicStats[1] > 0) { 00076 avgEventsPerRB = (int)(parent->basicStats[0] / parent->basicStats[1]); 00077 if (avgEventsPerRB < 1) { 00078 avgEventsPerRB = 1; 00079 } 00080 } 00081 00082 // ======== attempt 1 ======== 00083 #if ALGORITHM_TO_USE == 1 00084 if (rbFlag) { 00085 recentAvgRBLeashCount++; 00086 recentTotalRBLeash += timeLeash; 00087 // initial rollback calculation to quickly set recentAvgRBLeash to a reasonable value 00088 if (initialAvgRBLeashCalc) { 00089 recentAvgRBLeash = avgRBoffset; 00090 recentTotalRBLeash = 0; 00091 recentAvgRBLeashCount = 0; 00092 initialAvgRBLeashCalc = false; 00093 } 00094 // calculate the recent average timeleash when rollbacks occur 00095 if (recentAvgRBLeashCount >= AVG_LEASH_CALC_PERIOD) { 00096 recentAvgRBLeash = recentTotalRBLeash / recentAvgRBLeashCount; 00097 recentTotalRBLeash = 0; 00098 recentAvgRBLeashCount = 0; 00099 } 00100 if (timeLeash > recentAvgRBLeash) { 00101 timeLeash = recentAvgRBLeash; 00102 } else { 00103 timeLeash = recentAvgRBLeash / 2; 00104 } 00105 } else { 00106 timeLeash += recentAvgEventSparsity; 00107 } 00108 00109 if (avgRBsPerGVTIter > MAX_RB_PER_GVT_ITER) { 00110 maxTimeLeash = recentAvgRBLeash / 2; 00111 } else { 00112 maxTimeLeash = (POSE_TimeType)MAX_LEASH_MULTIPLIER * (POSE_TimeType)recentAvgEventSparsity * (POSE_TimeType)avgEventsPerRB; 00113 } 00114 00115 if (maxTimeLeash > 50000) { 00116 maxTimeLeash = 50000; 00117 } 00118 if (timeLeash > maxTimeLeash) { 00119 timeLeash = maxTimeLeash; 00120 } 00121 if (timeLeash < 1) { 00122 timeLeash = 1; 00123 } 00124 #endif 00125 00126 // ======== attempt 2 ======== 00127 #if ALGORITHM_TO_USE == 2 00128 timeLeash = recentAvgEventSparsity * avgEventsPerRB; 00129 00130 if (timeLeash > 50000) { 00131 timeLeash = 50000; 00132 } 00133 00134 if (timeLeash < 1) { 00135 timeLeash = 1; 00136 } 00137 #endif 00138 00139 // ======== attempt 3 ======== 00140 #if ALGORITHM_TO_USE == 3 00141 timeLeash += recentAvgEventSparsity; 00142 00143 if (avgRBsPerGVTIter > MAX_RB_PER_GVT_ITER) { 00144 maxTimeLeash = ((POSE_TimeType)MAX_LEASH_MULTIPLIER * (POSE_TimeType)recentAvgEventSparsity * (POSE_TimeType)avgEventsPerRB) / (4 * (POSE_TimeType)avgRBsPerGVTIter); 00145 } else { 00146 maxTimeLeash = 1000; 00147 } 00148 00149 if (maxTimeLeash > 50000) { 00150 maxTimeLeash = 50000; 00151 } 00152 if (timeLeash > maxTimeLeash) { 00153 timeLeash = maxTimeLeash; 00154 } 00155 if (timeLeash < 1) { 00156 timeLeash = 1; 00157 } 00158 #endif 00159 00160 // ======== attempt 4 ======== 00161 #if ALGORITHM_TO_USE == 4 00162 if (timeLeash > 10000) { 00163 timeLeash = 10000; 00164 } 00165 if (timeLeash < 1) { 00166 timeLeash = 1; 00167 } 00168 #endif 00169 00170 00171 /* 00172 if (rbFlag) { 00173 GVT *localGVT = (GVT *)CkLocalBranch(TheGVT); 00174 int numRollbacks = parent->basicStats[1]; 00175 int numGVTIters = localGVT->gvtIterationCount; 00176 if (userObj->myHandle == 32) { 00177 CkPrintf("*** ROLLBACK: numRollbacks=%d numGVTIters=%d\n", numRollbacks, numGVTIters); 00178 } 00179 if ((numGVTIters > 0) && (((96 * numRollbacks) / numGVTIters) > 2)) { 00180 timeLeash = avgRBoffset; 00181 } else { 00182 timeLeash++; 00183 } 00184 } else { 00185 timeLeash++; 00186 } 00187 00188 if (timeLeash > (avgRBoffset << 1)) { 00189 timeLeash = avgRBoffset << 1; 00190 } 00191 */ 00192 00193 00194 // can also just hard-code the time leash 00195 // timeLeash = 1000; 00196 00197 00198 // if (stepCalls == 0) { 00199 // timeLeashTotal = 0LL; 00200 // } 00201 00202 // if (timeLeash < 1000000) { 00203 // stepCalls++; 00204 // timeLeashTotal += timeLeash; 00205 // } 00206 00207 /* 00208 if (itersAllowed < 1) { 00209 itersAllowed = 1; 00210 } 00211 else { 00212 itersAllowed = (int)((double)specEventCount * specTol); 00213 itersAllowed -= specEventCount - eventCount; 00214 if (itersAllowed < 1) itersAllowed = 1; 00215 } 00216 */ 00217 00218 00219 // Prepare to execute an event 00220 offset = lastGVT + timeLeash; 00221 // Shorten the leash as we near POSE_endtime 00222 if ((POSE_endtime > POSE_UnsetTS) && ((offset > POSE_endtime) || 00223 (offset <= POSE_UnsetTS))) 00224 offset = POSE_endtime; 00225 00226 while ((ev->timestamp > POSE_UnsetTS) && (ev->timestamp <= offset) ){ 00227 #ifdef MEM_COARSE 00228 // Check to see if we should hold off on forward execution to save on 00229 // memory. 00230 // NOTE: to avoid deadlock, make sure we have executed something 00231 // beyond current GVT before worrying about memory usage 00232 if (((ev->timestamp > lastGVT) || (userObj->OVT() > lastGVT)) 00233 && (eq->mem_usage > objUsage)) { // don't deadlock 00234 break; 00235 } 00236 #endif 00237 00238 iter++; 00239 currentEvent = ev; 00240 ev->done = 2; 00241 localPVT->incSpecEventCount(); 00242 localPVT->incEventCount(); 00243 specEventCount++; 00244 eventCount++; 00245 #if !CMK_TRACE_DISABLED 00246 if(pose_config.trace) 00247 critStart = CmiWallTimer(); // trace timing 00248 #endif 00249 parent->ResolveFn(ev->fnIdx, ev->msg); // execute it 00250 #if !CMK_TRACE_DISABLED 00251 if(pose_config.trace) 00252 traceUserBracketEvent(10, critStart, CmiWallTimer()); 00253 #endif 00254 ev->done = 1; // flag the event as executed 00255 eq->mem_usage++; 00256 eq->ShiftEvent(); // shift to next event 00257 ev = eq->currentPtr; 00258 } 00259 #if !CMK_TRACE_DISABLED 00260 if(pose_config.stats) 00261 if (iter > 0) localStats->Loop(); 00262 #endif 00263 }