00001
00005
00006 #include "elements.h"
00007 #include "ckheap.h"
00008 #include "NeighborLB.h"
00009
00010 CreateLBFunc_Def(NeighborLB, "The neighborhood load balancer")
00011
00012 NeighborLB::NeighborLB(const CkLBOptions &opt):NborBaseLB(opt)
00013 {
00014 lbname = "NeighborLB";
00015 if (CkMyPe() == 0)
00016 CkPrintf("[%d] NeighborLB created\n",CkMyPe());
00017 }
00018
00019 LBMigrateMsg* NeighborLB::Strategy(NborBaseLB::LDStats* stats, int n_nbrs)
00020 {
00021 #if CMK_LBDB_ON
00022
00023
00024
00025 double myload = myStats.total_walltime - myStats.idletime;
00026 double avgload = myload;
00027 int i;
00028 for(i=0; i < n_nbrs; i++) {
00029
00030 const double scale = ((double)myStats.pe_speed)
00031 / stats[i].pe_speed;
00032
00033 stats[i].total_walltime *= scale;
00034 stats[i].idletime *= scale;
00035
00036 avgload += (stats[i].total_walltime - stats[i].idletime);
00037 }
00038 avgload /= (n_nbrs + 1);
00039
00040 CkVec<MigrateInfo*> migrateInfo;
00041
00042 if (myload > avgload) {
00043 if (_lb_args.debug()>1)
00044 CkPrintf("[%d] OVERLOAD My load is %f, average load is %f\n", CkMyPe(),myload,avgload);
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 minHeap procs(n_nbrs);
00055 for(i=0; i < n_nbrs; i++) {
00056 InfoRecord* item = new InfoRecord;
00057 item->load = stats[i].total_walltime - stats[i].idletime;
00058 item->Id = stats[i].from_pe;
00059 procs.insert(item);
00060 }
00061
00062 maxHeap objs(myStats.n_objs);
00063 for(i=0; i < myStats.n_objs; i++) {
00064 InfoRecord* item = new InfoRecord;
00065 item->load = myStats.objData[i].wallTime;
00066 item->Id = i;
00067 objs.insert(item);
00068 }
00069
00070 int objs_here = myStats.n_objs;
00071 do {
00072 if (objs_here <= 1) break;
00073
00074 InfoRecord* p;
00075 InfoRecord* obj;
00076
00077
00078 p = procs.deleteMin();
00079 if (p == 0) {
00080
00081 break;
00082 }
00083
00084
00085 CmiBool objfound = CmiFalse;
00086 do {
00087 obj = objs.deleteMax();
00088 if (obj == 0) break;
00089
00090 double new_p_load = p->load + obj->load;
00091 double my_new_load = myload - obj->load;
00092 if (new_p_load < my_new_load) {
00093
00094 objfound = CmiTrue;
00095 } else {
00096
00097
00098
00099 delete obj;
00100 }
00101 } while (!objfound);
00102
00103 if (!objfound) {
00104 if (_lb_args.debug()>2)
00105 CkPrintf("[%d] No suitable object found!\n",CkMyPe());
00106 break;
00107 }
00108
00109 const int me = CkMyPe();
00110
00111
00112
00113
00114 MigrateInfo* migrateMe = new MigrateInfo;
00115 migrateMe->obj = myStats.objData[obj->Id].handle;
00116 migrateMe->from_pe = me;
00117 migrateMe->to_pe = p->Id;
00118 migrateInfo.insertAtEnd(migrateMe);
00119
00120 objs_here--;
00121
00122
00123
00124 p->load += obj->load;
00125 myload -= obj->load;
00126 procs.insert(p);
00127
00128
00129 delete obj;
00130
00131 } while(myload > avgload);
00132
00133
00134 InfoRecord* p;
00135 while (NULL!=(p=procs.deleteMin()))
00136 delete p;
00137
00138 InfoRecord* obj;
00139 while (NULL!=(obj=objs.deleteMax()))
00140 delete obj;
00141 }
00142
00143
00144 int migrate_count=migrateInfo.length();
00145
00146
00147
00148 LBMigrateMsg* msg = new(migrate_count,CkNumPes(),CkNumPes(),0) LBMigrateMsg;
00149 msg->n_moves = migrate_count;
00150 for(i=0; i < migrate_count; i++) {
00151 MigrateInfo* item = (MigrateInfo*) migrateInfo[i];
00152 msg->moves[i] = *item;
00153 delete item;
00154 migrateInfo[i] = 0;
00155 }
00156
00157 return msg;
00158 #else
00159 return NULL;
00160 #endif
00161 }
00162
00163 #include "NeighborLB.def.h"
00164