libs/ck-libs/pose/gvt.C

Go to the documentation of this file.
00001 // Global Virtual Time estimation for POSE
00002 #include "pose.h"
00003 #include "srtable.h"
00004 #include "gvt.def.h"
00005 #include "qd.h"
00006 
00007 CkGroupID ThePVT;
00008 CkGroupID TheGVT;
00009 CpvExtern(int, stateRecovery);
00010 CpvExtern(eventID, theEventID);
00012 PVT::PVT() 
00013 {
00014 #ifdef VERBOSE_DEBUG
00015   CkPrintf("[%d] constructing PVT\n",CkMyPe());
00016 #endif
00017   CpvInitialize(int, stateRecovery);
00018   CpvAccess(stateRecovery) = 0;
00019   CpvInitialize(eventID, theEventID);
00020   CpvAccess(theEventID)=eventID();
00021   //  CpvAccess(theEventID).dump();
00022   LBTurnInstrumentOff();
00023   optGVT = POSE_UnsetTS; conGVT = POSE_UnsetTS;
00024   rdone=0;
00025   SRs=NULL;
00026 #ifdef POSE_COMM_ON
00027   //comm_debug = 1;
00028 #endif
00029 #ifndef CMK_OPTIMIZE
00030   localStats = (localStat *)CkLocalBranch(theLocalStats);
00031   if(pose_config.stats)
00032     {
00033       localStats->TimerStart(GVT_TIMER);
00034     }
00035 #endif
00036 #ifdef MEM_TEMPORAL
00037   localTimePool = (TimePool *)CkLocalBranch(TempMemID);
00038   CkPrintf("NOTE: Temporal memory manager is ON!\n");
00039 #endif
00040   optPVT = conPVT = estGVT = POSE_UnsetTS;
00041   startPhaseActive = gvtTurn = simdone = 0;
00042   SendsAndRecvs = new SRtable();
00043   SendsAndRecvs->Initialize();
00044   specEventCount = eventCount = waitForFirst = 0;
00045   iterMin = POSE_UnsetTS;
00046   int P=CkNumPes(), N=CkMyPe();
00047   reportReduceTo =  -1;
00048   if ((N < P-2) && (N%2 == 1)) { //odd
00049     reportTo = N-1;
00050     reportsExpected = reportEnd = 0;
00051   }
00052   else if (N < P-2) { //even
00053     reportTo = N;
00054     reportsExpected = 2; 
00055     if (N == P-3)
00056       reportsExpected = 1;
00057     reportEnd = 0;
00058     if (N < (P-2)/2)
00059       reportReduceTo = P-2;
00060     else reportReduceTo = P-1;
00061   }
00062   if (N == P-2) {
00063     reportTo = N;
00064     reportEnd = 1;
00065     reportsExpected = 1 + (P-2)/4 + ((P-2)%4)/2;
00066   }
00067   else if (N == P-1) {
00068     reportTo = N;
00069     reportEnd = 1;
00070     if (P==1) reportsExpected = 1;
00071     else reportsExpected = 1 + (P-2)/4 + (P-2)%2;
00072   }
00073   //  CkPrintf("PE %d reports to %d, receives %d reports, reduces and sends to %d, and reports directly to GVT if %d = 1!\n", CkMyPe(), reportTo, reportsExpected, reportReduceTo, reportEnd);
00074 #ifndef CMK_OPTIMIZE
00075   if(pose_config.stats)
00076     localStats->TimerStop();
00077 #endif
00078 }
00079 
00080 void PVT::startPhaseExp(prioBcMsg *m) {
00081   startPhase(m);
00082 }
00083 
00085 void PVT::startPhase(prioBcMsg *m) 
00086 {
00087   CProxy_GVT g(TheGVT);
00088   CProxy_PVT p(ThePVT);
00089   register int i;
00090 
00091   if (startPhaseActive) return;
00092 #ifndef CMK_OPTIMIZE
00093   if(pose_config.stats)
00094     localStats->TimerStart(GVT_TIMER);
00095 #endif
00096   startPhaseActive = 1;
00097   if (m->bc) {
00098     prioBcMsg *startMsg = new (8*sizeof(POSE_TimeType)) prioBcMsg;
00099     startMsg->bc = 0;
00100     *((POSE_TimeType *)CkPriorityPtr(startMsg)) = 1-POSE_TimeMax;
00101     CkSetQueueing(startMsg, CK_QUEUEING_IFIFO); 
00102     p.startPhaseExp(startMsg);
00103   }
00104 
00105   objs.Wake(); // wake objects to make sure all have reported
00106   // compute PVT
00107   optPVT = conPVT = POSE_UnsetTS;
00108   int end = objs.getNumSpaces();
00109   for (i=0; i<end; i++)
00110     if (objs.objs[i].isPresent()) {
00111       if (objs.objs[i].isOptimistic()) { // check optPVT 
00112         if ((optPVT < 0) || ((objs.objs[i].getOVT() < optPVT) && 
00113                              (objs.objs[i].getOVT() > POSE_UnsetTS))) {
00114           optPVT = objs.objs[i].getOVT();
00115           CkAssert(simdone>0 || ((objs.objs[i].getOVT() >= estGVT) ||
00116                                (objs.objs[i].getOVT() == POSE_UnsetTS)));
00117         }
00118       }
00119       else if (objs.objs[i].isConservative()) { // check conPVT
00120         if ((conPVT < 0) || ((objs.objs[i].getOVT() < conPVT) && 
00121                              (objs.objs[i].getOVT() > POSE_UnsetTS)))
00122           conPVT = objs.objs[i].getOVT();
00123       }
00124       CkAssert(simdone>0 || (optPVT >= estGVT)||(optPVT == POSE_UnsetTS)||(estGVT == POSE_UnsetTS));
00125       CkAssert(simdone>0 || (conPVT >= estGVT)||(conPVT == POSE_UnsetTS)||(estGVT == POSE_UnsetTS));
00126     }
00127 
00128   // (1) Find out the local PVT from optPVT and conPVT
00129   POSE_TimeType pvt = optPVT;
00130   if ((conPVT < pvt) && (conPVT > POSE_UnsetTS)) pvt = conPVT;
00131   if ((iterMin < pvt) && (iterMin > POSE_UnsetTS)) pvt = iterMin;
00132   if (waitForFirst) {
00133     waitForFirst = 0;
00134     if (pvt == POSE_UnsetTS)
00135       SendsAndRecvs->Restructure(estGVT, estGVT, POSE_UnsetTS);
00136     else
00137       SendsAndRecvs->Restructure(estGVT, pvt, POSE_UnsetTS);
00138   }
00139 
00140   //  CkPrintf("[%d] pvt=%d gvt=%d optPVT=%d iterMin=%d\n", CkMyPe(), pvt, estGVT, optPVT, iterMin);
00141   POSE_TimeType xt;
00142   if (pvt == POSE_UnsetTS) { // all are idle; find max ovt
00143     POSE_TimeType maxOVT = POSE_UnsetTS;
00144     for (i=0; i<end; i++)
00145       if (objs.objs[i].isPresent()) {
00146         xt = objs.objs[i].getOVT2();
00147         if (xt > maxOVT)
00148           maxOVT = xt;
00149       }
00150     if (maxOVT > estGVT)
00151       pvt = maxOVT;
00152   }
00153   
00154   // (2) Pack the SRtable data into the message
00155   POSE_TimeType maxSR;
00156   UpdateMsg *um = SendsAndRecvs->PackTable(pvt, &maxSR);
00157   // (3) Add the PVT info to the message
00158   um->optPVT = pvt;
00159   um->conPVT = conPVT;
00160   um->maxSR = maxSR;
00161   um->runGVTflag = 0;
00162 
00163   if (um->numEntries > 0) {
00164     //CkPrintf("PE %d has %d SRs reported to GVT; earliest=%d pvt=%d\n", CkMyPe(), um->numEntries, um->SRs[0].timestamp, pvt);
00165   }
00166   // send data to GVT estimation
00167   p[reportTo].reportReduce(um);
00168 
00169   /*
00170   if (simdone) // transmit final info to GVT on PE 0
00171     g[0].computeGVT(um);              
00172   else {
00173     g[gvtTurn].computeGVT(um);           // transmit info to GVT
00174     gvtTurn = (gvtTurn + 1) % CkNumPes();  // calculate next GVT location
00175   }
00176   */
00177   objs.SetIdle(); // Set objects to idle
00178   iterMin = POSE_UnsetTS;
00179 #ifndef CMK_OPTIMIZE
00180   if(pose_config.stats)
00181     localStats->TimerStop();
00182 #endif
00183 }
00184 
00186 void PVT::setGVT(GVTMsg *m)
00187 {
00188 #ifndef CMK_OPTIMIZE
00189   if(pose_config.stats)
00190     localStats->TimerStart(GVT_TIMER);
00191 #endif
00192   CProxy_PVT p(ThePVT);
00193   CkAssert(m->estGVT >= estGVT);
00194   estGVT = m->estGVT;
00195   int i, end = objs.getNumSpaces();
00196 #ifdef POSE_COMM_ON  
00197   //PrioStreaming *pstrat = (PrioStreaming *)(POSE_commlib_insthndl.getStrategy());
00198   //pstrat->setBasePriority((estGVT+10) - POSE_TimeMax);
00199   //pstrat->setBasePriority(estGVT+10);
00200 #endif
00201   simdone = m->done;
00202   CkFreeMsg(m);
00203   waitForFirst = 1;
00204   objs.Commit();
00205 #ifdef MEM_TEMPORAL
00206   localTimePool->set_min_time(estGVT);
00207 #endif
00208   startPhaseActive = 0;
00209   prioBcMsg *startMsg = new (8*sizeof(int)) prioBcMsg;
00210   startMsg->bc = 1;
00211   *((int *)CkPriorityPtr(startMsg)) = 0;
00212   CkSetQueueing(startMsg, CK_QUEUEING_IFIFO); 
00213   p[CkMyPe()].startPhase(startMsg);
00214 #ifndef CMK_OPTIMIZE
00215   if(pose_config.stats)
00216     localStats->TimerStop();
00217 #endif
00218 }
00219 
00221 int PVT::objRegister(int arrIdx, POSE_TimeType safeTime, int sync, sim *myPtr)
00222 {
00223   int i = objs.Insert(arrIdx, POSE_UnsetTS, sync, myPtr); // add to object list
00224   return(i*1000 + CkMyPe());                          // return unique PVT idx
00225 }
00226 
00227 // Unregister poser from PVT
00228 void PVT::objRemove(int pvtIdx)
00229 {
00230   int idx = (pvtIdx-CkMyPe())/1000;  // calculate local index from unique index
00231   objs.Delete(idx);                  // delete the object
00232 }
00233 
00235 void PVT::objUpdate(POSE_TimeType timestamp, int sr)
00236 {
00237 #ifndef CMK_OPTIMIZE
00238   int tstat = localStats->TimerRunning();
00239   if(pose_config.stats){
00240     if (tstat)
00241       localStats->SwitchTimer(GVT_TIMER);
00242     else
00243       localStats->TimerStart(GVT_TIMER);
00244   }
00245 #endif
00246   //if ((timestamp < estGVT) && (estGVT > POSE_UnsetTS))
00247   //CkPrintf("timestamp=%d estGVT=%d simdone=%d sr=%d\n", timestamp,
00248   //estGVT, simdone, sr);
00249   CkAssert(simdone>0 || (timestamp >= estGVT) || (estGVT == POSE_UnsetTS));
00250   CkAssert((sr == SEND) || (sr == RECV));
00251   if ((estGVT > POSE_UnsetTS) && 
00252       ((timestamp < iterMin) || (iterMin == POSE_UnsetTS))) 
00253     iterMin = timestamp;
00254   if (waitForFirst) {
00255     waitForFirst = 0;
00256     SendsAndRecvs->Restructure(estGVT, timestamp, sr);
00257   }
00258   else SendsAndRecvs->Insert(timestamp, sr);
00259 #ifndef CMK_OPTIMIZE
00260   if(pose_config.stats){
00261     if (tstat)
00262       localStats->SwitchTimer(tstat);
00263     else
00264       localStats->TimerStop();
00265   }
00266 #endif
00267 
00268 }
00269 
00271 void PVT::objUpdateOVT(int pvtIdx, POSE_TimeType safeTime, POSE_TimeType ovt)
00272 {
00273   int index = (pvtIdx-CkMyPe())/1000;
00274   // minimize the non-idle OVT
00275   //  if ((safeTime < estGVT) && (safeTime > POSE_UnsetTS)) 
00276 
00277   CkAssert(simdone>0 || (safeTime >= estGVT) || (safeTime == POSE_UnsetTS));
00278   if ((safeTime == POSE_UnsetTS) && (objs.objs[index].getOVT2() < ovt))
00279     objs.objs[index].setOVT2(ovt);
00280   else if ((safeTime > POSE_UnsetTS) && 
00281            ((objs.objs[index].getOVT() > safeTime) || (objs.objs[index].getOVT() == POSE_UnsetTS)))
00282     objs.objs[index].setOVT(safeTime);
00283 }
00284 
00286 void PVT::reportReduce(UpdateMsg *m)
00287 {
00288 #ifndef CMK_OPTIMIZE
00289   if(pose_config.stats)
00290     localStats->TimerStart(GVT_TIMER);
00291 #endif
00292   CProxy_PVT p(ThePVT);
00293   CProxy_GVT g(TheGVT);
00294   POSE_TimeType lastGVT = 0, maxSR=0;
00295 
00296   // see if message provides new min optGVT or conGVT
00297   if ((optGVT < 0) || ((m->optPVT > POSE_UnsetTS) && (m->optPVT < optGVT)))
00298     optGVT = m->optPVT;
00299   if (m->maxSR > 0)
00300     maxSR = m->maxSR;
00301   addSR(&SRs, m->SRs, optGVT, m->numEntries);
00302   rdone++;
00303   CkFreeMsg(m);
00304 
00305   if (rdone == reportsExpected) { // all PVT reports are in
00306     UpdateMsg *um;
00307     int entryCount = 0;
00308     // pack data into um
00309     SRentry *tmp = SRs;
00310     while (tmp && ((tmp->timestamp <= optGVT) || (optGVT == POSE_UnsetTS))
00311            && (tmp->sends != tmp->recvs)) {
00312       entryCount++;
00313       tmp = tmp->next;
00314     }
00315     um = new (entryCount * sizeof(SRentry), 0) UpdateMsg;
00316     tmp = SRs;
00317     int i=0;
00318     while (tmp && ((tmp->timestamp <= optGVT) || (optGVT == POSE_UnsetTS))
00319            && (tmp->sends != tmp->recvs)) {
00320       um->SRs[i] = *tmp;
00321       tmp = tmp->next;
00322       i++;
00323     }
00324     um->numEntries = entryCount;
00325     um->optPVT = optGVT;
00326     um->conPVT = conGVT;
00327     um->maxSR = maxSR;
00328     um->runGVTflag = 0;
00329 
00330     if (reportEnd) { //send to computeGVT
00331       if (simdone>0) // transmit final info to GVT on PE 0
00332         g[0].computeGVT(um);              
00333       else {
00334         g[gvtTurn].computeGVT(um);           // transmit info to GVT
00335         gvtTurn = (gvtTurn + 1) % CkNumPes();  // calculate next GVT location
00336       }
00337     }
00338     else { //send to pvt reportReduceTo
00339       p[reportReduceTo].reportReduce(um);
00340     }
00341 
00342     // reset static data
00343     optGVT = conGVT = POSE_UnsetTS;
00344     SRentry *cur = SRs;
00345     SRs = NULL;
00346     while (cur) {
00347       tmp = cur->next;
00348       delete cur;
00349       cur = tmp;
00350     }
00351     rdone = 0;
00352   }
00353 #ifndef CMK_OPTIMIZE
00354   if(pose_config.stats)
00355     localStats->TimerStop();
00356 #endif
00357 }
00358 
00360 GVT::GVT() 
00361 {
00362 #ifdef VERBOSE_DEBUG
00363   CkPrintf("[%d] constructing GVT\n",CkMyPe());
00364 #endif
00365 
00366   optGVT = POSE_UnsetTS, conGVT = POSE_UnsetTS;
00367   done=0;
00368   SRs = NULL;
00369   startOffset = 0;
00370 
00371 #ifndef CMK_OPTIMIZE
00372   localStats = (localStat *)CkLocalBranch(theLocalStats);
00373 #endif
00374 #ifndef SEQUENTIAL_POSE
00375   if(pose_config.lb_on)
00376     nextLBstart = pose_config.lb_skip - 1;
00377 #endif
00378   estGVT = lastEarliest = inactiveTime = POSE_UnsetTS;
00379   lastSends = lastRecvs = inactive = 0;
00380   reportsExpected = 1;
00381   if (CkNumPes() >= 2) reportsExpected = 2;
00382     
00383   //  CkPrintf("GVT expects %d reports!\n", reportsExpected);
00384   if (CkMyPe() == 0) { // start the PVT phase of the GVT algorithm
00385     CProxy_PVT p(ThePVT);
00386     prioBcMsg *startMsg = new (8*sizeof(int)) prioBcMsg;
00387     startMsg->bc = 1;
00388     *((int *)CkPriorityPtr(startMsg)) = 0;
00389     CkSetQueueing(startMsg, CK_QUEUEING_IFIFO); 
00390     p.startPhase(startMsg); // broadcast PVT calculation to all PVT branches
00391   }
00392 }
00393 
00394 // Used for Ccd calls; currently commented out
00395 //void GVT::_runGVT(UpdateMsg *m) 
00396 //{ 
00397 //  CProxy_GVT g(TheGVT);
00398 //  g[(CkMyPe() + 1)%CkNumPes()].runGVT(m);
00399 //}
00400 
00402 void GVT::runGVT(UpdateMsg *m) 
00403 {
00404 #ifndef CMK_OPTIMIZE
00405   if(pose_config.stats)
00406     localStats->TimerStart(GVT_TIMER);
00407 #endif
00408   estGVT = m->optPVT;
00409   inactive = m->inactive;
00410   inactiveTime = m->inactiveTime;
00411   nextLBstart = m->nextLB;
00412   CProxy_GVT g(TheGVT);
00413   m->runGVTflag = 1;
00414   g[CkMyPe()].computeGVT(m);  // start the next PVT phase of the GVT algorithm
00415 #ifndef CMK_OPTIMIZE
00416   if(pose_config.stats)
00417     localStats->TimerStop();
00418 #endif
00419 }
00420 
00422 void GVT::computeGVT(UpdateMsg *m)
00423 {
00424 #ifndef CMK_OPTIMIZE
00425   if(pose_config.stats)
00426     localStats->TimerStart(GVT_TIMER);
00427 #endif
00428   CProxy_PVT p(ThePVT);
00429   CProxy_GVT g(TheGVT);
00430   GVTMsg *gmsg = new GVTMsg;
00431   POSE_TimeType lastGVT = 0, earliestMsg = POSE_UnsetTS, 
00432     earlyAny = POSE_UnsetTS;
00433 
00434   if (CkMyPe() != 0) startOffset = 1;
00435   if (m->runGVTflag == 1) done++;
00436   else {
00437     // see if message provides new min optGVT or conGVT
00438     if ((optGVT < 0) || ((m->optPVT > POSE_UnsetTS) && (m->optPVT < optGVT)))
00439       optGVT = m->optPVT;
00440     if ((conGVT < 0) || ((m->conPVT > POSE_UnsetTS) && (m->conPVT < conGVT)))
00441       conGVT = m->conPVT;
00442     if (m->maxSR > earlyAny) 
00443       earlyAny = m->maxSR;
00444     // add send/recv info to SRs
00445     /*    if (m->numEntries > 0)
00446       CkPrintf("GVT recv'd %d SRs from a PE, earliest=%d\n", m->numEntries, 
00447       m->SRs[0].timestamp);*/
00448     addSR(&SRs, m->SRs, optGVT, m->numEntries);
00449     done++;
00450   }
00451   CkFreeMsg(m);
00452 
00453   if (done == reportsExpected+startOffset) { // all PVT reports are in
00454 #ifndef CMK_OPTIMIZE
00455     if(pose_config.stats)
00456       localStats->GvtInc();
00457 #endif
00458     done = 0;
00459     startOffset = 1;
00460     lastGVT = estGVT; // store previous estimate
00461     if (lastGVT < 0) lastGVT = 0;
00462     estGVT = POSE_UnsetTS;
00463     
00464     // derive GVT estimate from min optimistic & conservative GVTs
00465     estGVT = optGVT;
00466     if ((conGVT > POSE_UnsetTS) && (estGVT > POSE_UnsetTS) && (conGVT < estGVT))  estGVT = conGVT;
00467 
00468     // Check if send/recv activity provides lower possible estimate
00469     /*    if (SRs) SRs->dump();
00470           else CkPrintf("No SRs reported to GVT!\n");*/
00471     SRentry *tmp = SRs;
00472     POSE_TimeType lastSR = POSE_UnsetTS;
00473     while (tmp && ((tmp->timestamp <= estGVT) || (estGVT == POSE_UnsetTS))) {
00474       lastSR = tmp->timestamp;
00475       if (tmp->sends != tmp->recvs) {
00476         earliestMsg = tmp->timestamp;
00477         break;
00478       }
00479       tmp = tmp->next;
00480     }
00481     /*    if ((earliestMsg > POSE_UnsetTS) || (earlyAny > POSE_UnsetTS))
00482           CkPrintf("GVT: earlyDiff=%d earlyAny=%d estGVT was %d.\n", earliestMsg, earlyAny, estGVT);*/
00483     if (((earliestMsg < estGVT) && (earliestMsg != POSE_UnsetTS)) ||
00484         (estGVT == POSE_UnsetTS))
00485       estGVT = earliestMsg;
00486     if ((lastSR != POSE_UnsetTS) && (estGVT == POSE_UnsetTS) && 
00487         (lastSR > lastGVT))
00488       estGVT = lastSR;
00489 
00490     // check for inactivity
00491     if ((optGVT == POSE_UnsetTS) && (earliestMsg == POSE_UnsetTS)) {
00492       inactive++;
00493       /*
00494       if (inactive == 1) {
00495         CkPrintf("[%d] Inactive... calling CkWaitQD...\n", CkMyPe());
00496         CkWaitQD();
00497         CkPrintf("[%d] Back from CkWaitQD...\n", CkMyPe());
00498       }
00499       */
00500       estGVT = lastGVT;
00501       if (inactive == 1) inactiveTime = lastGVT;
00502     }
00503     else if (estGVT < 0) {
00504       estGVT = lastGVT;
00505       inactive = 0;
00506     }
00507     else inactive = 0;
00508 
00509     // check the estimate
00510     //CkPrintf("opt=%d con=%d lastGVT=%d early=%d lastSR=%d et=%d\n", optGVT, conGVT, lastGVT, earliestMsg, lastSR, POSE_endtime);
00511     CmiAssert(estGVT >= lastGVT); 
00512     //if (estGVT % 1000 == 0)
00513     //CkPrintf("[%d] New GVT = %d\n", CkMyPe(), estGVT);
00514     //CkPrintf("[%d] New GVT = %lld\n", CkMyPe(), estGVT);
00515 
00516     // check for termination conditions
00517     int term = 0;
00518     if ((estGVT >= POSE_endtime) && (POSE_endtime > POSE_UnsetTS)) {
00519 #if USE_LONG_TIMESTAMPS      
00520       CkPrintf("At endtime: %lld\n", POSE_endtime);
00521 #else
00522       CkPrintf("At endtime: %d\n", POSE_endtime);
00523 #endif
00524       term = 1;
00525     }
00526     else if (inactive > 2) {
00527 #if USE_LONG_TIMESTAMPS      
00528       CkPrintf("Simulation inactive at time: %lld\n", inactiveTime);
00529 #else
00530       CkPrintf("Simulation inactive at time: %d\n", inactiveTime);
00531 #endif
00532       term = 1;
00533     }
00534 
00535     // report the last new GVT estimate to all PVT branches
00536     gmsg->estGVT = estGVT;
00537     gmsg->done = term;
00538     if (term) {
00539       //if (POSE_endtime > POSE_UnsetTS) gmsg->estGVT = POSE_endtime + 1;
00540       // else gmsg->estGVT++;
00541 #if USE_LONG_TIMESTAMPS      
00542       CkPrintf("Final GVT = %lld\n", gmsg->estGVT);
00543 #else
00544       CkPrintf("Final GVT = %d\n", gmsg->estGVT);
00545 #endif
00546       p.setGVT(gmsg);
00547       POSE_stop();
00548     }
00549     else {
00550       p.setGVT(gmsg);
00551 
00552       if(pose_config.lb_on)
00553         {
00554           // perform load balancing
00555 #ifndef CMK_OPTIMIZE
00556           if(pose_config.stats)
00557             localStats->SwitchTimer(LB_TIMER);
00558 #endif
00559          
00560           if (CkNumPes() > 1) {
00561             nextLBstart++;
00562             if (pose_config.lb_skip == nextLBstart) {
00563               TheLBG.calculateLocalLoad();
00564               nextLBstart = 0;
00565             }
00566           }
00567 #ifndef CMK_OPTIMIZE
00568           if(pose_config.stats)
00569             localStats->SwitchTimer(GVT_TIMER);
00570 #endif
00571         }
00572 
00573       // transmit data to start next GVT estimation on next GVT branch
00574       UpdateMsg *umsg = new UpdateMsg;
00575       umsg->maxSR=0;
00576       umsg->optPVT = estGVT;
00577       umsg->inactive = inactive;
00578       umsg->inactiveTime = inactiveTime;
00579       umsg->nextLB = nextLBstart;
00580       umsg->runGVTflag = 0;
00581       g[(CkMyPe()+1) % CkNumPes()].runGVT(umsg);
00582     }
00583 
00584     // reset static data
00585     optGVT = conGVT = POSE_UnsetTS;
00586     SRentry *cur = SRs;
00587     SRs = NULL;
00588     while (cur) {
00589       tmp = cur->next;
00590       delete cur;
00591       cur = tmp;
00592     }
00593   }
00594 #ifndef CMK_OPTIMIZE
00595   if(pose_config.stats)
00596     localStats->TimerStop();
00597 #endif
00598 }
00599 
00600 void GVT::addSR(SRentry **SRs, SRentry *e, POSE_TimeType og, int ne)
00601 {
00602   register int i;
00603   SRentry *tab = (*SRs);
00604   SRentry *tmp = tab;
00605 
00606   for (i=0; i<ne; i++) {
00607     if ((e[i].timestamp < og) || (og == POSE_UnsetTS)) {
00608       if (!tmp) { // no entries yet
00609         tab = new SRentry(e[i].timestamp, (SRentry *)NULL);
00610         tab->sends = e[i].sends;
00611         tab->recvs = e[i].recvs;
00612         tmp = tab;
00613         *SRs = tmp;
00614       }
00615       else {
00616         if (e[i].timestamp < tmp->timestamp) { // goes before tmp
00617           CkAssert(tmp == *SRs);
00618           tab = new SRentry(e[i].timestamp, tmp);
00619           tab->sends = e[i].sends;
00620           tab->recvs = e[i].recvs;
00621           tmp = tab;
00622           *SRs = tmp;
00623         }
00624         else if (e[i].timestamp == tmp->timestamp) { // goes in first entr
00625           tmp->sends = tmp->sends + e[i].sends;
00626           tmp->recvs = tmp->recvs + e[i].recvs;
00627         }
00628         else { // search for position
00629           while (tmp->next && (e[i].timestamp > tmp->next->timestamp))
00630             tmp = tmp->next;
00631           if (!tmp->next) { // goes at end of SRs
00632             tmp->next = new SRentry(e[i].timestamp, (SRentry *)NULL);
00633             tmp->next->sends = tmp->next->sends + e[i].sends;
00634             tmp->next->recvs = tmp->next->recvs + e[i].recvs;
00635             tmp = tmp->next;
00636           }
00637           else if (e[i].timestamp == tmp->next->timestamp) {//goes in tmp->next
00638             tmp->next->sends = tmp->next->sends + e[i].sends;
00639             tmp->next->recvs = tmp->next->recvs + e[i].recvs;
00640             tmp = tmp->next;
00641           }
00642           else { // goes after tmp but before tmp->next
00643             tmp->next = new SRentry(e[i].timestamp, tmp->next);
00644             tmp->next->sends = tmp->next->sends + e[i].sends;
00645             tmp->next->recvs = tmp->next->recvs + e[i].recvs;
00646             tmp = tmp->next;
00647           }
00648         }
00649       }
00650     }
00651     else break;
00652   }
00653 }
00654 
00655 void PVT::addSR(SRentry **SRs, SRentry *e, POSE_TimeType og, int ne)
00656 {
00657   register int i;
00658   SRentry *tab = (*SRs);
00659   SRentry *tmp = tab;
00660 
00661   for (i=0; i<ne; i++) {
00662     if ((e[i].timestamp < og) || (og == POSE_UnsetTS)) {
00663       if (!tmp) { // no entries yet
00664         tab = new SRentry(e[i].timestamp, (SRentry *)NULL);
00665         tab->sends = e[i].sends;
00666         tab->recvs = e[i].recvs;
00667         tmp = tab;
00668         *SRs = tmp;
00669       }
00670       else {
00671         if (e[i].timestamp < tmp->timestamp) { // goes before tmp
00672           CkAssert(tmp == *SRs);
00673           tab = new SRentry(e[i].timestamp, tmp);
00674           tab->sends = e[i].sends;
00675           tab->recvs = e[i].recvs;
00676           tmp = tab;
00677           *SRs = tmp;
00678         }
00679         else if (e[i].timestamp == tmp->timestamp) { // goes in first entr
00680           tmp->sends = tmp->sends + e[i].sends;
00681           tmp->recvs = tmp->recvs + e[i].recvs;
00682         }
00683         else { // search for position
00684           while (tmp->next && (e[i].timestamp > tmp->next->timestamp))
00685             tmp = tmp->next;
00686           if (!tmp->next) { // goes at end of SRs
00687             tmp->next = new SRentry(e[i].timestamp, (SRentry *)NULL);
00688             tmp->next->sends = tmp->next->sends + e[i].sends;
00689             tmp->next->recvs = tmp->next->recvs + e[i].recvs;
00690             tmp = tmp->next;
00691           }
00692           else if (e[i].timestamp == tmp->next->timestamp) {//goes in tmp->next
00693             tmp->next->sends = tmp->next->sends + e[i].sends;
00694             tmp->next->recvs = tmp->next->recvs + e[i].recvs;
00695             tmp = tmp->next;
00696           }
00697           else { // goes after tmp but before tmp->next
00698             tmp->next = new SRentry(e[i].timestamp, tmp->next);
00699             tmp->next->sends = tmp->next->sends + e[i].sends;
00700             tmp->next->recvs = tmp->next->recvs + e[i].recvs;
00701             tmp = tmp->next;
00702           }
00703         }
00704       }
00705     }
00706     else break;
00707   }
00708 }

Generated on Sun Jun 29 13:29:25 2008 for Charm++ by  doxygen 1.5.1