/home/coin/SVN-release/OS-2.0.1/Bcp/src/Member/BCP_process.cpp

Go to the documentation of this file.
00001 // (C) 2007 Copyright International Business Machines Corporation
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Pierre Bonami, International Business Machines Corporation
00007 // Andreas Waechter, International Business Machines Corporation
00008 // Laszlo Ladanyi, International Business Machines Corporation
00009 //
00010 // Date : 10/03/2007
00011 
00012 #include "CoinTime.hpp"
00013 #include "BCP_process.hpp"
00014 
00015 #ifndef BCP_DEBUG_PRINT
00016 #define BCP_DEBUG_PRINT 0
00017 #endif
00018 
00019 BCP_scheduler::BCP_scheduler():
00020     totalNumberIds_(0),
00021     freeIds_(),
00022     numNodeIds_(0),
00023     maxNodeIds_(1),
00024     maxNodeIdRatio_(1.0),
00025     maxNodeIdNum_(1)
00026 {}
00027 
00028 void
00029 BCP_scheduler::setParams(double OverEstimationStatic,
00030                          double SwitchToRateThreshold,
00031                          double TimeRootNodeSolve,
00032                          double FactorTimeHorizon,
00033                          double OverEstimationRate,
00034                          double MaxNodeIdRatio,
00035                          int    MaxNodeIdNum,
00036                          int    MaxSbIds,
00037                          int    MinSbIds)
00038 {
00039   rho_static_ = OverEstimationStatic;
00040   switch_thresh_ = SwitchToRateThreshold;
00041   numSecRateInterval_ = (int)ceil(TimeRootNodeSolve*FactorTimeHorizon);
00042   request_counts_.reserve(numSecRateInterval_+1);
00043   request_counts_.insert(request_counts_.end(), numSecRateInterval_+1, -1);
00044   request_counts_tot_ = 0;
00045   release_counts_.reserve(numSecRateInterval_+1);
00046   release_counts_.insert(release_counts_.end(), numSecRateInterval_+1, -1);
00047   release_counts_tot_ = 0;
00048   counts_ptr_ = 0;
00049   time_last_action_ = 0;
00050   static_ = true;
00051   have_rates_ = false;
00052   rho_rate_ = OverEstimationRate;
00053   maxNodeIdRatio_ = MaxNodeIdRatio;
00054   maxNodeIdNum_ = MaxNodeIdNum;
00055   maxNodeIds_ = CoinMin((int)floor(maxNodeIdRatio_ * totalNumberIds_),
00056                         maxNodeIdNum_);
00057   if (maxNodeIds_ == 0) {
00058     maxNodeIds_ = 1;
00059   }
00060   maxSbIds_ = MaxSbIds;
00061   // printf("Setting max SbIds to %i\n",maxSbIds_);
00062   minSbIds_ = MinSbIds;
00063 }
00064 
00065 //------------------------------------------------------------------------------
00066 void
00067 BCP_scheduler::add_free_ids(int numIds, const int* ids)
00068 {
00069   freeIds_.insert(freeIds_.end(), ids, ids+numIds);
00070   totalNumberIds_ += numIds;
00071   maxNodeIds_ = CoinMin((int)floor(maxNodeIdRatio_ * totalNumberIds_),
00072                         maxNodeIdNum_);
00073   const double t = CoinWallclockTime();
00074   for (int i = 0; i < numIds; ++i) {
00075     sb_idle_time_[ids[i]] = 0.0;
00076     node_idle_time_[ids[i]] = 0.0;
00077     last_release_time_[ids[i]] = t;
00078     last_release_type_[ids[i]] = 0;
00079   }
00080 }
00081 
00082 //------------------------------------------------------------------------------
00083 
00084 int
00085 BCP_scheduler::request_sb_ids(int reqNumIds, int* ids)
00086 {
00087   // increase the count for requests by one
00088   update_rates(1, 0);
00089 
00090   int numIds = CoinMin(reqNumIds, max_id_allocation(reqNumIds));
00091 #if (BCP_DEBUG_PRINT != 0)
00092   if (static_) {
00093     printf("SC static:  req: %i  given: %i  total: %i  node(max): %i(%i)  free: %i  minSb: %i  maxSb: %i  rho: %lf\n",
00094            reqNumIds, numIds, totalNumberIds_, numNodeIds_, maxNodeIds_,
00095            (int)freeIds_.size(), minSbIds_, maxSbIds_, rho_static_);
00096   } else {
00097     printf("SC rate:  req: %i  given: %i  total: %i  node(max): %i(%i)  free: %i  minSb: %i  maxSb: %i  rho: %lf  rel_cnt: %i  req_cnt: %i\n",
00098            reqNumIds, numIds, totalNumberIds_, numNodeIds_, maxNodeIds_,
00099            (int)freeIds_.size(), minSbIds_, maxSbIds_, rho_rate_,
00100            release_counts_tot_, request_counts_tot_);
00101   }
00102 #endif
00103   if (numIds==0) return 0;
00104 
00105   const int newsize = freeIds_.size() - numIds;
00106   CoinDisjointCopyN(&freeIds_[newsize], numIds, ids);
00107   freeIds_.erase(freeIds_.begin()+newsize, freeIds_.end()); 
00108   const double t = CoinWallclockTime();
00109   for (int i = 0; i < numIds; ++i) {
00110     const int id = ids[i];
00111     if (last_release_type_[id] != 2) {
00112       sb_idle_time_[id] += t - last_release_time_[id];
00113     } else {
00114       node_idle_time_[id] += t - last_release_time_[id];
00115     }
00116   }
00117   return numIds;
00118 }
00119 
00120 void
00121 BCP_scheduler::release_sb_id(int id)
00122 {
00123   // increase the count for releases by one
00124   update_rates(0, 1);
00125   freeIds_.push_back(id);
00126   last_release_time_[id] = CoinWallclockTime();
00127   last_release_type_[id] = 1;
00128 }
00129 
00130 //------------------------------------------------------------------------------
00131 
00134 int
00135 BCP_scheduler::request_node_id()
00136 {
00137   if (freeIds_.empty() || numNodeIds_ == maxNodeIds_) return -1;
00138   numNodeIds_ ++;
00139   int id = freeIds_.back();
00140   freeIds_.pop_back();
00141   return id;
00142 }
00143 
00144 void
00145 BCP_scheduler::release_node_id(int id)
00146 {
00147   // increase the count for releases by one
00148   update_rates(0, 1);
00149   freeIds_.push_back(id);
00150   last_release_time_[id] = CoinWallclockTime();
00151   last_release_type_[id] = 2;
00152   numNodeIds_--;
00153 }
00154 
00155 //------------------------------------------------------------------------------
00156 
00157 void
00158 BCP_scheduler::update_idle_times()
00159 {
00160   const double t = CoinWallclockTime();
00161   for (int i = freeIds_.size()-1; i >= 0; --i) {
00162     const int id = freeIds_[i];
00163     if (last_release_type_[id] != 2) {
00164       sb_idle_time_[id] += t - last_release_time_[id];
00165     } else {
00166       node_idle_time_[id] += t - last_release_time_[id];
00167     }
00168   }
00169 }
00170     
00171 
00172 //------------------------------------------------------------------------------
00173 
00174 void
00175 BCP_scheduler::update_rates(int add_req, int add_rel)
00176 {
00177   // Update the counts for the requests
00178   time_t time_now = time(NULL);
00179   if (time_now == time_last_action_) {
00180     request_counts_[counts_ptr_] += add_req;;
00181     release_counts_[counts_ptr_] += add_rel;;
00182   }
00183   else if (time_last_action_ == 0) {
00184     counts_ptr_ = 0;
00185     request_counts_[counts_ptr_] = add_req;
00186     release_counts_[counts_ptr_] = add_rel;
00187     time_last_action_ = time_now;
00188   }
00189   else {
00190     while (time_last_action_ < time_now) {
00191       request_counts_tot_ += request_counts_[counts_ptr_];
00192       release_counts_tot_ += release_counts_[counts_ptr_];
00193       counts_ptr_++;
00194       if (counts_ptr_ > numSecRateInterval_) {
00195         counts_ptr_ = 0;
00196         have_rates_ = true;
00197       }
00198       if (have_rates_) {
00199         request_counts_tot_ -= request_counts_[counts_ptr_];
00200         release_counts_tot_ -= release_counts_[counts_ptr_];
00201       }
00202       request_counts_[counts_ptr_] = 0;
00203       release_counts_[counts_ptr_] = 0;
00204 
00205       time_last_action_++;
00206     }
00207     request_counts_[counts_ptr_] = add_req;
00208     release_counts_[counts_ptr_] = add_rel;
00209 
00210     static_ = (!have_rates_ || freeIds_.size() >= (1.-switch_thresh_)*(totalNumberIds_-numNodeIds_) );
00211   }
00212 }
00213 
00214 //------------------------------------------------------------------------------
00215 
00216 int 
00217 BCP_scheduler::max_id_allocation(int numIds)
00218 {
00219   double dretval;
00220   int retval;
00221 
00222   /* FIXME: this might be incorrect if in request_node_ids() more than 1 id is
00223      requested. If only LPs processes are used then it's correct. */
00224 
00225   const int numFree = freeIds_.size();
00226 
00227   double expRate =
00228     (double)CoinMin(2*numNodeIds_,maxNodeIds_) / (double)numNodeIds_;
00229 
00230   if (static_) {
00231     dretval = (rho_static_ * (double)(totalNumberIds_-numNodeIds_*expRate) /
00232                (double)(numNodeIds_*expRate) );
00233   }
00234   else {
00235     if (request_counts_tot_ == 0) {
00236       dretval = numFree;
00237     }
00238     else {
00239       dretval = (rho_rate_ * (double)(release_counts_tot_) /
00240                 (double)(request_counts_tot_));
00241     }
00242   }
00243   retval = CoinMin(numFree, (int)floor(dretval));
00244 
00245   if (numIds >= minSbIds_ && retval < minSbIds_) {
00246     retval = 0;
00247   }
00248   if (retval > maxSbIds_) {
00249     retval = maxSbIds_;
00250   }
00251 
00252   // At this point, we only want to send an odd number of processors
00253   if (retval && (retval & 1) == 0) {
00254     --retval;
00255   }
00256 
00257   return retval;
00258 }

Generated on Thu Oct 8 03:02:52 2009 by  doxygen 1.4.7