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