00001 #ifndef __CACHEMANAGER_H__
00002 #define __CACHEMANAGER_H__
00003
00004 #include <sys/types.h>
00005 #include <vector>
00006 #include <map>
00007 #include <set>
00008 #include "charm++.h"
00009 #include "envelope.h"
00010
00011 #if COSMO_STATS > 0
00012 #include <fstream>
00013 #endif
00014
00022 typedef CmiUInt8 CkCacheKey;
00023
00024 typedef struct _CkCacheUserData {
00025 CmiUInt8 d0;
00026 CmiUInt8 d1;
00027 } CkCacheUserData;
00028
00029
00030 class CkCacheEntryType;
00031 class CkCacheRequestorData;
00032 class CkCacheEntry;
00033
00034 #include "CkCache.decl.h"
00035
00036 class CkCacheStatistics {
00037 CmiUInt8 dataArrived;
00038 CmiUInt8 dataTotalArrived;
00039 CmiUInt8 dataMisses;
00040 CmiUInt8 dataLocal;
00041 CmiUInt8 dataError;
00042 CmiUInt8 totalDataRequested;
00043 CmiUInt8 maxData;
00044 int index;
00045
00046 CkCacheStatistics() : dataArrived(0), dataTotalArrived(0),
00047 dataMisses(0), dataLocal(0), dataError(0),
00048 totalDataRequested(0), maxData(0), index(-1) { }
00049
00050 public:
00051 CkCacheStatistics(CmiUInt8 pa, CmiUInt8 pta, CmiUInt8 pm,
00052 CmiUInt8 pl, CmiUInt8 pe, CmiUInt8 tpr,
00053 CmiUInt8 mp, int i) :
00054 dataArrived(pa), dataTotalArrived(pta), dataMisses(pm),
00055 dataLocal(pl), dataError(pe), totalDataRequested(tpr),
00056 maxData(mp), index(i) { }
00057
00058 void printTo(CkOStream &os) {
00059 os << " Cache: " << dataTotalArrived << " data arrived (corresponding to ";
00060 os << dataArrived << " messages), " << dataLocal << " from local Chares" << endl;
00061 if (dataError > 0) {
00062 os << "Cache: ======>>>> ERROR: " << dataError << " data messages arrived without being requested!! <<<<======" << endl;
00063 }
00064 os << " Cache: " << dataMisses << " misses during computation" << endl;
00065 os << " Cache: Maximum of " << maxData << " data stored at a time in processor " << index << endl;
00066 os << " Cache: local Chares made " << totalDataRequested << " requests" << endl;
00067 }
00068
00069 static CkReduction::reducerType sum;
00070
00071 static CkReductionMsg *sumFn(int nMsg, CkReductionMsg **msgs) {
00072 CkCacheStatistics ret;
00073 ret.maxData = 0;
00074 for (int i=0; i<nMsg; ++i) {
00075 CkAssert(msgs[i]->getSize() == sizeof(CkCacheStatistics));
00076 CkCacheStatistics *data = (CkCacheStatistics *)msgs[i]->getData();
00077 ret.dataArrived += data->dataArrived;
00078 ret.dataTotalArrived += data->dataTotalArrived;
00079 ret.dataMisses += data->dataMisses;
00080 ret.dataLocal += data->dataLocal;
00081 ret.totalDataRequested += data->totalDataRequested;
00082 if (data->maxData > ret.maxData) {
00083 ret.maxData = data->maxData;
00084 ret.index = data->index;
00085 }
00086 }
00087 return CkReductionMsg::buildNew(sizeof(CkCacheStatistics), &ret);
00088 }
00089 };
00090
00091 class CkCacheRequestMsg : public CMessage_CkCacheRequestMsg {
00092 public:
00093 CkCacheKey key;
00094 int replyTo;
00095 CkCacheRequestMsg(CkCacheKey k, int reply) : key(k), replyTo(reply) { }
00096 };
00097
00098 class CkCacheFillMsg : public CMessage_CkCacheFillMsg {
00099 public:
00100 CkCacheKey key;
00101 char *data;
00102 CkCacheFillMsg (CkCacheKey k) : key(k) {}
00103 };
00104
00105 typedef void (*CkCacheCallback)(CkArrayID, CkArrayIndex&, CkCacheKey, CkCacheUserData &, void*, int);
00106
00107 class CkCacheRequestorData {
00108 public:
00109 CkCacheUserData userData;
00110 CkCacheCallback fn;
00111 CkArrayID requestorID;
00112 CkArrayIndex requestorIdx;
00113
00114 CkCacheRequestorData(CProxyElement_ArrayElement &el, CkCacheCallback f, CkCacheUserData &data) {
00115 userData = data;
00116 requestorID = el.ckGetArrayID();
00117 requestorIdx = el.ckGetIndex();
00118 fn = f;
00119 }
00120
00121 void deliver(CkCacheKey key, void *data, int chunk) {
00122 fn(requestorID, requestorIdx, key, userData, data, chunk);
00123 }
00124 };
00125
00126 class CkCacheEntryType {
00127 public:
00128 virtual void * request(CkArrayIndex&, CkCacheKey) = 0;
00129 virtual void * unpack(CkCacheFillMsg *, int, CkArrayIndex &) = 0;
00130 virtual void writeback(CkArrayIndex&, CkCacheKey, void *) = 0;
00131 virtual void free(void *) = 0;
00132 virtual int size(void *) = 0;
00133 };
00134
00135 class CkCacheEntry {
00136 public:
00137 CkCacheKey key;
00138 CkArrayIndex home;
00139 CkCacheEntryType *type;
00140 std::vector<CkCacheRequestorData> requestorVec;
00141
00142 void *data;
00143
00144 bool requestSent;
00145 bool replyRecvd;
00146 bool writtenBack;
00147 #if COSMO_STATS > 1
00149 int totalRequests;
00152 int misses;
00153 #endif
00154 CkCacheEntry(CkCacheKey key, CkArrayIndex &home, CkCacheEntryType *type) {
00155 replyRecvd = false;
00156 requestSent = false;
00157 writtenBack = false;
00158 data = NULL;
00159 this->key = key;
00160 this->home = home;
00161 this->type = type;
00162 #if COSMO_STATS > 1
00163 totalRequests=0;
00164 misses=0;
00165 #endif
00166 }
00167
00168 ~CkCacheEntry() {
00169 CkAssert(requestorVec.empty());
00170 if (!writtenBack) writeback();
00171 type->free(data);
00172 }
00173
00174 inline void writeback() {
00175 type->writeback(home, key, data);
00176 writtenBack = true;
00177 }
00178 };
00179
00180 class CkCacheArrayCounter : public CkLocIterator {
00181 public:
00182 int count;
00183 CkHashtableT<CkArrayIndex, int> registered;
00184 CkCacheArrayCounter() : count(0) { }
00185 void addLocation(CkLocation &loc) {
00186 registered.put(loc.getIndex()) = ++count;
00187 }
00188 void reset() {
00189 count = 0;
00190 registered.empty();
00191 }
00192 };
00193
00194 class CkCacheManager : public CBase_CkCacheManager {
00195
00196
00197
00198
00199
00201 int numChunks;
00203 int finishedChunks;
00204
00207 CkCacheArrayCounter localChares;
00210 CkCacheArrayCounter localCharesWB;
00212 int syncdChares;
00213
00215 int numLocMgr;
00218 CkGroupID *locMgr;
00220 int numLocMgrWB;
00223 CkGroupID *locMgrWB;
00224
00225 #if COSMO_STATS > 0
00227 CmiUInt8 dataArrived;
00230 CmiUInt8 dataTotalArrived;
00232 CmiUInt8 dataMisses;
00234 CmiUInt8 dataLocal;
00236 CmiUInt8 dataError;
00237
00239 CmiUInt8 totalDataRequested;
00241 CmiUInt8 maxData;
00242 #endif
00243
00246 CmiUInt8 *chunkWeight;
00247
00249 CmiUInt8 maxSize;
00250
00252 int *chunkAck;
00254 int *chunkAckWB;
00255
00257 std::map<CkCacheKey,CkCacheEntry*> *cacheTable;
00258 int storedData;
00259
00262 std::map<CkCacheKey,int> outStandingRequests;
00263
00264
00265
00266
00267
00268 public:
00269
00270 CkCacheManager(int size, CkGroupID gid);
00271 CkCacheManager(int size, int n, CkGroupID *gid);
00272 CkCacheManager(int size, int n, CkGroupID *gid, int nWB, CkGroupID *gidWB);
00273 CkCacheManager(CkMigrateMessage *m);
00274 ~CkCacheManager() {}
00275 void pup(PUP::er &p);
00276 private:
00277 void init();
00278 public:
00279
00280 void * requestData(CkCacheKey what, CkArrayIndex &toWhom, int chunk, CkCacheEntryType *type, CkCacheRequestorData &req);
00281 void * requestDataNoFetch(CkCacheKey key, int chunk);
00282 CkCacheEntry * requestCacheEntryNoFetch(CkCacheKey key, int chunk);
00283 void recvData(CkCacheFillMsg *msg);
00284 void recvData(CkCacheKey key, CkArrayIndex &from, CkCacheEntryType *type, int chunk, void *data);
00285
00286 void cacheSync(int &numChunks, CkArrayIndex &chareIdx, int &localIdx);
00287
00290 void writebackChunk(int num);
00293 void finishedChunk(int num, CmiUInt8 weight);
00298 void collectStatistics(CkCallback& cb);
00299 std::map<CkCacheKey,CkCacheEntry*> *getCache();
00300
00301 };
00302
00303 #endif