00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "CommLB.h"
00018
00019 #define alpha 35e-6
00020 #define beta 8.5e-9
00021
00022 #define LOWER_FACTOR 0.33
00023 #define UPPER_FACTOR 0.67
00024 #define MAX_WEIGHT 5.0
00025
00026 extern int quietModeRequested;
00027
00028 CreateLBFunc_Def(CommLB, "another variation of CommLB")
00029
00030 CommLB::CommLB(const CkLBOptions &opt): CBase_CommLB(opt)
00031 {
00032 if (CkMyPe() == 0 && !quietModeRequested)
00033 CkPrintf("CharmLB> CommLB created.\n");
00034 lbname = "CommLB";
00035 }
00036
00037 bool CommLB::QueryBalanceNow(int _step)
00038 {
00039
00040 return true;
00041 }
00042
00043 void CommLB::alloc(int pe , int id, double load, int nmsg, int nbyte){
00044 alloc_array[npe][id].load = 1.0;
00045 alloc_array[pe][id].load = load;
00046 alloc_array[pe][id].nmsg = nmsg;
00047 alloc_array[pe][id].nbyte = nbyte;
00048 alloc_array[pe][nobj].load += load;
00049 alloc_array[pe][nobj].nmsg += nmsg;
00050 alloc_array[pe][nobj].nbyte += nbyte;
00051 }
00052
00053 double CommLB::compute_cost(int id, int pe, int n_alloc, int &com_msg, int &com_data){
00054 int j;
00055 double total_cost, com_cost, weight=0.0;
00056 graph * ptr;
00057 double bound1,bound2;
00058
00059 bound1 = LOWER_FACTOR * nobj;
00060 bound2 = UPPER_FACTOR * nobj;
00061
00062 if(n_alloc <= (int)bound1)
00063 weight = MAX_WEIGHT;
00064 else if((n_alloc > (int)bound1)&&(n_alloc < (int)bound2))
00065 weight = (bound2 - n_alloc)/(bound2 - bound1) * (MAX_WEIGHT - 1) + 1;
00066 else if(n_alloc >= (int)bound2)
00067 weight = 1.0;
00068
00069
00070 ptr = object_graph[id].next;
00071
00072 com_msg = 0;
00073 com_data = 0;
00074 for(j=0;(j<2*nobj)&&(ptr != NULL);j++,ptr=ptr->next){
00075 if(alloc_array[npe][ptr->id].load == 0.0)
00076 continue;
00077 if(alloc_array[pe][ptr->id].load > 0.0)
00078 continue;
00079 com_data += ptr->data;
00080 com_msg += ptr->nmsg;
00081 }
00082 com_cost = weight * (alpha*(com_msg + alloc_array[pe][nobj].nmsg) + beta*(com_data + alloc_array[pe][nobj].nbyte));
00083
00084 total_cost = alloc_array[pe][nobj].load + com_cost;
00085 return total_cost;
00086 }
00087
00088 void CommLB::add_graph(int x, int y, int data, int nmsg){
00089 graph * ptr, *temp;
00090
00091
00092 ptr = &(object_graph[x]);
00093 for(;ptr->next != NULL; ptr = ptr->next);
00094
00095 temp = new graph;
00096
00097 temp->id = y;
00098 temp->data = data;
00099 temp->nmsg = nmsg;
00100 temp->next = NULL;
00101
00102 ptr->next = temp;
00103
00104 ptr = &(object_graph[y]);
00105 for(;ptr->next != NULL; ptr = ptr->next);
00106
00107 temp = new graph;
00108
00109 temp->id = x;
00110 temp->data = data;
00111 temp->nmsg = nmsg;
00112 temp->next = NULL;
00113
00114 ptr->next = temp;
00115 }
00116
00117
00118 void init(alloc_struct **a, graph * object_graph, int l, int b){
00119 int i,j;
00120
00121 for(i=0;i<l+1;i++)
00122 for(j=0;j<b+1;j++){
00123 a[i][j].load = 0.0;
00124 a[i][j].nbyte = 0;
00125 a[i][j].nmsg = 0;
00126 }
00127
00128 for(j=0;j<b;j++){
00129 object_graph[j].data = 0;
00130 object_graph[j].nmsg = 0;
00131 object_graph[j].next = NULL;
00132 }
00133 }
00134
00135 void CommLB::work(LDStats* stats)
00136 {
00137 int pe,obj,com;
00138 double mean_load =0.0;
00139 ObjectRecord *x;
00140
00141
00142
00143 nobj = stats->n_objs;
00144 npe = stats->nprocs();
00145
00146 stats->makeCommHash();
00147
00148 alloc_array = new alloc_struct *[npe + 1];
00149
00150 object_graph = new graph[nobj];
00151
00152 for(pe = 0; pe <= npe; pe++)
00153 alloc_array[pe] = new alloc_struct[nobj +1];
00154
00155 init(alloc_array,object_graph,npe,nobj);
00156
00157 ObjectHeap maxh(nobj+1);
00158 for(obj=0; obj < nobj; obj++) {
00159 LDObjData &objData = stats->objData[obj];
00160 int onpe = stats->from_proc[obj];
00161 x = new ObjectRecord;
00162 x->id = obj;
00163 x->pos = obj;
00164 x->val = objData.wallTime;
00165 x->pe = onpe;
00166 maxh.insert(x);
00167 mean_load += objData.wallTime;
00168 }
00169 mean_load /= npe;
00170
00171 int xcoord=0,ycoord=0;
00172
00173 for(com =0; com< stats->n_comm;com++) {
00174 LDCommData &commData = stats->commData[com];
00175 if((!commData.from_proc())&&(commData.recv_type()==LD_OBJ_MSG)){
00176 xcoord = stats->getHash(commData.sender);
00177 ycoord = stats->getHash(commData.receiver.get_destObj());
00178 if((xcoord == -1)||(ycoord == -1)) {
00179 if (_lb_args.ignoreBgLoad()) continue;
00180 else CkAbort("Error in search\n");
00181 }
00182 add_graph(xcoord,ycoord,commData.bytes, commData.messages);
00183 }
00184 }
00185
00186 int id,maxid,spe=0,minpe=0,mpos;
00187 double temp_cost,min_cost;
00188
00189 pe = 0;
00190 x = maxh.deleteMax();
00191 maxid = x->id;
00192 spe = x->pe;
00193 mpos = x->pos;
00194
00195 alloc(pe,maxid,stats->objData[mpos].wallTime,0,0);
00196 if(pe != spe){
00197
00198 CmiAssert(stats->from_proc[mpos] == spe);
00199 stats->to_proc[mpos] = pe;
00200 }
00201
00202 int out_msg,out_byte,min_msg,min_byte;
00203
00204 for(id = 1;id<nobj;id++){
00205 x = maxh.deleteMax();
00206
00207 maxid = x->id;
00208 spe = x->pe;
00209 mpos = x->pos;
00210 LDObjData &objData = stats->objData[mpos];
00211
00212 if (!objData.migratable) {
00213 if (!stats->procs[spe].available) {
00214 CmiAbort("Load balancer is not be able to move a nonmigratable object out of an unavailable processor.\n");
00215 }
00216 temp_cost = compute_cost(maxid,spe,id,out_msg,out_byte);
00217 alloc(spe, maxid, x->val, out_msg, out_byte);
00218 continue;
00219 }
00220
00221 for(pe =0; pe < npe; pe++)
00222 if((alloc_array[pe][nobj].load <= mean_load)||(id >= UPPER_FACTOR*nobj))
00223 break;
00224 CmiAssert(pe < npe);
00225
00226 temp_cost = compute_cost(maxid,pe,id,out_msg,out_byte);
00227 min_cost = temp_cost;
00228 minpe = pe;
00229 min_msg = out_msg;
00230 min_byte = out_byte;
00231 pe++;
00232 for(; pe < npe; pe++) {
00233 if((alloc_array[pe][nobj].load > mean_load) && (id < UPPER_FACTOR*nobj))
00234 continue;
00235 temp_cost = compute_cost(maxid,pe,id,out_msg,out_byte);
00236 if(min_cost > temp_cost){
00237 minpe = pe;
00238 min_cost = temp_cost;
00239 min_msg = out_msg;
00240 min_byte = out_byte;
00241 }
00242 }
00243 CmiAssert(minpe < npe);
00244
00245 alloc(minpe, maxid, x->val, min_msg, min_byte);
00246
00247 if(minpe != spe){
00248
00249 CmiAssert(stats->from_proc[mpos] == spe);
00250 stats->to_proc[mpos] = minpe;
00251 }
00252 }
00253 }
00254
00255 #include "CommLB.def.h"
00256