This commit is contained in:
LYC 2024-10-30 14:06:23 +08:00
parent 00c46e16e9
commit dacff5ba53
7 changed files with 107 additions and 124 deletions

View File

@ -30,15 +30,22 @@ NewCache::NewCache(Config *config)
this->config = config; this->config = config;
if (config->L2_size > 0) if (config->L2_size > 0)
{ {
l2 = new Cache(config->blockSize, config->L2_size, config->L2_assoc, 0, "L2"); CacheConfig* cacheConfig2 = new CacheConfig(config->blockSize, config->L2_size, config->L2_assoc, 0,LRU,LFU, string("L2"));
l1 = new Cache(config->blockSize, config->L1_size, config->L1_assoc, config->victimCacheSize, l2, "L1"); l2 = new Cache(cacheConfig2,nullptr);
CacheConfig* cacheConfig1 = new CacheConfig(config->blockSize, config->L1_size, config->L1_assoc, config->victimCacheSize,LRU,LFU, string("L1"));
l1 = new Cache(cacheConfig1,l2);
isL2Exist = config->L2_size, isVictimExist = config->victimCacheSize; isL2Exist = config->L2_size, isVictimExist = config->victimCacheSize;
} }
else else
{ {
l2 = nullptr; l2 = nullptr;
l1 = new Cache(config->blockSize, config->L1_size, config->L1_assoc, config->victimCacheSize, nullptr, "L1");
CacheConfig* cacheConfig1 = new CacheConfig(config->blockSize, config->L1_size, config->L1_assoc, config->victimCacheSize,LRU,LFU, string("L1"));
l1 = new Cache(cacheConfig1,l2);
isL2Exist = config->L2_size, isVictimExist = config->victimCacheSize; isL2Exist = config->L2_size, isVictimExist = config->victimCacheSize;
} }
} }
@ -46,26 +53,26 @@ NewCache::NewCache(Config *config)
void NewCache::printNewCache() void NewCache::printNewCache()
{ {
cout << "====== Simulation results (raw) ======" << endl; cout << "====== Simulation results (raw) ======" << endl;
cout << setw(38) << "a. number of L1 reads: " << this->l1->r << endl; cout << setw(38) << "a. number of L1 reads: " << this->l1->readCount << endl;
cout << setw(38) << "b. number of L1 read misses: " << this->l1->rm << endl; cout << setw(38) << "b. number of L1 read misses: " << this->l1->readMiss << endl;
cout << "c. number of L1 writes: " << this->l1->w << endl; cout << "c. number of L1 writes: " << this->l1->writeCount << endl;
cout << setw(38) << "d. number of L1 write misses: " << this->l1->wm << endl; cout << setw(38) << "d. number of L1 write misses: " << this->l1->writeMiss << endl;
cout << setw(38) << "e. L1 miss rate: " << fixed << setprecision(4) << this->l1->getMR() << endl; cout << setw(38) << "e. L1 miss rate: " << fixed << setprecision(4) << this->l1->getMR() << endl;
cout << setw(38) << "f. number of swaps: " << this->l1->ex << endl; cout << setw(38) << "f. number of swaps: " << this->l1->exchange << endl;
cout << setw(38) << "g. number of victim cache writeback: " << (this->isVictimExist ? this->l1->wb : 0) << endl; cout << setw(38) << "g. number of victim cache writeback: " << (this->isVictimExist ? this->l1->writeBack : 0) << endl;
if (this->isL2Exist) if (this->isL2Exist)
{ {
cout << setw(38) << "h. number of L2 reads: " << this->l2->r << endl; cout << setw(38) << "h. number of L2 reads: " << this->l2->readCount << endl;
cout << setw(38) << "i. number of L2 read misses: " << this->l2->rm << endl; cout << setw(38) << "i. number of L2 read misses: " << this->l2->readMiss << endl;
cout << setw(38) << "j. number of L2 writes: " << this->l2->w << endl; cout << setw(38) << "j. number of L2 writes: " << this->l2->writeCount << endl;
cout << setw(38) << "k. number of L2 write misses: " << this->l2->wm << endl; cout << setw(38) << "k. number of L2 write misses: " << this->l2->writeMiss << endl;
cout << setw(38) << "l. L2 miss rate: " << fixed << setprecision((this->isL2Exist) ? 4 : 0) << this->l2->getMR2() << endl; cout << setw(38) << "l. L2 miss rate: " << fixed << setprecision((this->isL2Exist) ? 4 : 0) << this->l2->getMR2() << endl;
cout << setw(38) << "m. number of L2 writebacks: " << this->l2->wb << endl; cout << setw(38) << "m. number of L2 writebacks: " << this->l2->writeBack << endl;
cout << setw(38) << "n. total memory traffic: " << (this->l2->rm + this->l2->wm + this->l2->wb) << endl; cout << setw(38) << "n. total memory traffic: " << (this->l2->readMiss + this->l2->writeMiss + this->l2->writeBack) << endl;
cout << "==== Simulation results (performance) ====" << endl; cout << "==== Simulation results (performance) ====" << endl;
double HT1 = this->l1->config.getHT(), MR1 = this->l1->getMR(); double HT1 = this->l1->config->getHT(), MR1 = this->l1->getMR();
double HT2 = this->l2->config.getHT2(), MR2 = this->l2->getMR2(); double HT2 = this->l2->config->getHT2(), MR2 = this->l2->getMR2();
double MP = this->l2->config.getMP(); double MP = this->l2->config->getMP();
cout << setw(32) << "1. average access time:" << fixed << setprecision(4) << HT1 + (MR1 * (HT2 + MR2 * MP)) << " ns" << endl; cout << setw(32) << "1. average access time:" << fixed << setprecision(4) << HT1 + (MR1 * (HT2 + MR2 * MP)) << " ns" << endl;
} }
else else
@ -76,11 +83,11 @@ void NewCache::printNewCache()
cout << setw(38) << "k. number of L2 write misses: " << 0 << endl; cout << setw(38) << "k. number of L2 write misses: " << 0 << endl;
cout << setw(38) << "l. L2 miss rate: " << 0 << endl; cout << setw(38) << "l. L2 miss rate: " << 0 << endl;
cout << setw(38) << "m. number of L2 writebacks: " << 0 << endl; cout << setw(38) << "m. number of L2 writebacks: " << 0 << endl;
cout << setw(38) << "n. total memory traffic: " << (this->l1->rm + this->l1->wm + this->l1->wb) << endl; cout << setw(38) << "n. total memory traffic: " << (this->l1->readMiss + this->l1->writeMiss + this->l1->writeBack) << endl;
cout << "==== Simulation results (performance) ====" << endl; cout << "==== Simulation results (performance) ====" << endl;
double ht = this->l1->config.getHT(); double ht = this->l1->config->getHT();
double mp = this->l1->config.getMP(); double mp = this->l1->config->getMP();
double mr = (this->l1->rm + this->l1->wm) / (double)(this->l1->r + this->l1->w); double mr = (this->l1->readMiss + this->l1->writeMiss) / (double)(this->l1->readCount + this->l1->writeCount);
cout << setw(32) << "1. average access time:" << fixed << setprecision(4) << ht + mr * mp << " ns" << endl; cout << setw(32) << "1. average access time:" << fixed << setprecision(4) << ht + mr * mp << " ns" << endl;
} }
} }

Binary file not shown.

View File

@ -13,8 +13,9 @@ int CacheConfig::ReplicementPolicy() { return replicementPolicy; }
int CacheConfig::WritePolicy() { return writePolicy; } int CacheConfig::WritePolicy() { return writePolicy; }
CacheConfig::CacheConfig() {} CacheConfig::CacheConfig() {}
CacheConfig::CacheConfig(int blockSize, int size, int ass, int vis, int rep, int wrp) CacheConfig::CacheConfig(int blockSize, int size, int ass, int vis, int rep, int wrp, string l)
{ {
this->level = l;
this->blockSize = blockSize; this->blockSize = blockSize;
this->s = size; this->s = size;
this->assoc = ass; this->assoc = ass;
@ -105,40 +106,28 @@ uint32_t CacheConfig::UnParserVic(uint32_t tag, CacheIndex tio)
{ {
return (tag << (vo)) | (tio.offset); return (tag << (vo)) | (tio.offset);
} }
Cache::Cache(int blockSize, int s, int assoc, int victimSize, string l, int replicementPolicy, int writePolicy)
Cache::Cache(CacheConfig* config, Cache* nextCache)
{ {
config = CacheConfig(blockSize, s, assoc, victimSize, replicementPolicy, writePolicy); this->config = config;
c.resize(config.getMaxIndex()); cache.resize(config->getMaxIndex());
this->level = l; for (auto &b : cache)
for (auto &b : c) b.resize(config->getAs());
b.resize(config.getAs());
if (victimSize)
vc.resize(config.getVictimAs());
}
Cache::Cache(int blockSize, int s, int assoc, int victimSize, Cache *n, string l, int replicementPolicy, int writePolicy) if (config->victimSize)
{ victimCache.resize(config->getVictimAs());
config = CacheConfig(blockSize, s, assoc, victimSize, replicementPolicy, writePolicy); this->nextCache = nextCache;
c.resize(config.getMaxIndex());
for (auto &b : c)
b.resize(config.getAs());
if (victimSize)
vc.resize(config.getVictimAs());
NextCache = n;
level = l;
} }
void Cache::useCache(uint32_t rawAddr, bool isWrite) void Cache::useCache(uint32_t rawAddr, bool isWrite)
{ {
isWrite ? Write() : Read(); isWrite ? writeCount++ : readCount++;
auto addr = config.AddrParser(rawAddr); auto addr = config->AddrParser(rawAddr);
auto s = &c[addr.index]; auto s = &cache[addr.index];
// Find in Cache // Find in Cache
auto cl = find_if( auto cl = find_if(
@ -146,7 +135,7 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
s->end(), s->end(),
[=](const Block &b) [=](const Block &b)
{ {
return b.v && b.tag == addr.tag; return b.valid && b.tag == addr.tag;
}); });
if (cl != s->end()) if (cl != s->end())
@ -155,7 +144,7 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
for (auto &b : (*s)) for (auto &b : (*s))
b.lru += (b.lru < cl->lru); b.lru += (b.lru < cl->lru);
cl->lru = 0; cl->lru = 0;
cl->d |= isWrite; cl->dirty |= isWrite;
return; return;
} }
@ -165,7 +154,7 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
s->end(), s->end(),
[](const Block &b) [](const Block &b)
{ {
return !b.v; return !b.valid;
}); });
if (cl == s->end()) if (cl == s->end())
@ -176,25 +165,25 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
s->end()); s->end());
} }
if (!vc.size()) if (!victimCache.size())
{ {
isWrite ? WriteMiss() : ReadMiss(); isWrite ? writeMiss++ : readMiss++;
// No Victim Cache // No Victim Cache
if (cl->v && cl->d) if (cl->valid && cl->dirty)
{ {
// Write to the L2 or Disk // Write to the L2 or Disk
WriteBack(); writeBack++;
if (NextCache != nullptr) if (nextCache != nullptr)
{ {
NextCache->useCache(config.UnParser(cl->tag, addr), true); nextCache->useCache(config->UnParser(cl->tag, addr), true);
} }
} }
if (NextCache != nullptr) if (nextCache != nullptr)
{ {
// 2. Find it from Next Level // 2. Find it from Next Level
NextCache->useCache(rawAddr, false); nextCache->useCache(rawAddr, false);
} }
for (auto &b : (*s)) for (auto &b : (*s))
@ -207,44 +196,44 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
// Miss Write or Read Miss, Go to Next Level // Miss Write or Read Miss, Go to Next Level
// 1. Find it from Victim Cache // 1. Find it from Victim Cache
auto vaddr = config.VictimAddrParser(rawAddr); auto vaddr = config->VictimAddrParser(rawAddr);
auto vcp = &vc; auto vcp = &victimCache;
auto vic = find_if( auto vic = find_if(
vcp->begin(), vcp->begin(),
vcp->end(), vcp->end(),
[=](const Block &b) [=](const Block &b)
{ {
return b.v && b.tag == vaddr.tag; return b.valid && b.tag == vaddr.tag;
}); });
if (vic != vcp->end()) if (vic != vcp->end())
{ {
// V. Cache Hit from Victim! // V. Cache Hit from Victim!
auto tmp = *vic; auto tmp = *vic;
if (cl->v) if (cl->valid)
{ {
for (auto &b : *vcp) for (auto &b : *vcp)
b.lru += (b.lru < tmp.lru); b.lru += (b.lru < tmp.lru);
*vic = {config.VictimAddrParser(config.UnParser(cl->tag, addr)).tag, 0, cl->d, true}; *vic = {config->VictimAddrParser(config->UnParser(cl->tag, addr)).tag, 0, cl->dirty, true};
} }
for (auto &b : (*s)) for (auto &b : (*s))
b.lru++; b.lru++;
*cl = {addr.tag, 0, isWrite || tmp.d, true}; *cl = {addr.tag, 0, isWrite || tmp.dirty, true};
Exchange(); exchange++;
return; return;
} }
// X. Victim Cache Miss! // X. Victim Cache Miss!
isWrite ? WriteMiss() : ReadMiss(); isWrite ? writeMiss++ : readMiss++;
if (!cl->v) if (!cl->valid)
{ {
if (NextCache != nullptr) if (nextCache != nullptr)
{ {
// 2. Find it from Next Level // 2. Find it from Next Level
NextCache->useCache(rawAddr, false); nextCache->useCache(rawAddr, false);
} }
// Empty Level 1 // Empty Level 1
for (auto &b : (*s)) for (auto &b : (*s))
@ -258,7 +247,7 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
vcp->end(), vcp->end(),
[=](const Block &b) [=](const Block &b)
{ {
return !b.v; return !b.valid;
}); });
if (vic == vcp->end()) if (vic == vcp->end())
@ -267,27 +256,27 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
vic = max_element( vic = max_element(
vcp->begin(), vcp->begin(),
vcp->end()); vcp->end());
if (vic->v && vic->d) if (vic->valid && vic->dirty)
{ {
WriteBack(); writeBack++;
if (NextCache != nullptr) if (nextCache != nullptr)
{ {
NextCache->useCache(config.UnParserVic(vic->tag, vaddr), true); nextCache->useCache(config->UnParserVic(vic->tag, vaddr), true);
} }
} }
} }
// New Victim Cache // New Victim Cache
for (auto &b : *vcp) for (auto &b : *vcp)
b.lru++; b.lru++;
*vic = {config.VictimAddrParser(config.UnParser(cl->tag, addr)).tag, 0, cl->d, true}; *vic = {config->VictimAddrParser(config->UnParser(cl->tag, addr)).tag, 0, cl->dirty, true};
for (auto &b : (*s)) for (auto &b : (*s))
b.lru++; b.lru++;
*cl = {addr.tag, 0, isWrite, true}; *cl = {addr.tag, 0, isWrite, true};
if (NextCache != nullptr) if (nextCache != nullptr)
{ {
// 2. Find it from Next Level // 2. Find it from Next Level
NextCache->useCache(rawAddr, false); nextCache->useCache(rawAddr, false);
} }
} }
@ -296,27 +285,27 @@ void Cache::useCache(uint32_t rawAddr, bool isWrite)
void Cache::printCache() void Cache::printCache()
{ {
if (!this->config.Size()) if (!this->config->Size())
return; return;
cout << "===== " << this->level << " contents =====" << endl; cout << "===== " << this->config->level << " contents =====" << endl;
for (unsigned i = 0; i != this->c.size(); i++) for (unsigned i = 0; i != this->cache.size(); i++)
{ {
cout << "set " << i << ": "; cout << "set " << i << ": ";
auto temp = this->c[i]; auto temp = this->cache[i];
stable_sort(temp.begin(), temp.end()); stable_sort(temp.begin(), temp.end());
for (auto b : temp) for (auto b : temp)
cout << hex << b.tag << (b.d ? " D " : " "); cout << hex << b.tag << (b.dirty ? " D " : " ");
cout << endl cout << endl
<< dec; << dec;
} }
if (this->vc.size()) if (this->victimCache.size())
{ {
cout << "===== Victim Cache contents =====" << endl; cout << "===== Victim Cache contents =====" << endl;
cout << "set 0: "; cout << "set 0: ";
auto temp = this->vc; auto temp = this->victimCache;
stable_sort(temp.begin(), temp.end()); stable_sort(temp.begin(), temp.end());
for (auto b : temp) for (auto b : temp)
cout << hex << b.tag << (b.d ? " D " : " "); cout << hex << b.tag << (b.dirty ? " D " : " ");
cout << endl cout << endl
<< dec; << dec;
} }
@ -324,25 +313,20 @@ void Cache::printCache()
double Cache::getMR() double Cache::getMR()
{ {
return (double)(rm + wm) / (double)(r + w); return (double)(readMiss + writeMiss) / (double)(readCount + writeCount);
} }
double Cache::getMR2() double Cache::getMR2()
{ {
return (double)(rm) / (double)(r); return (double)(readMiss) / (double)(readCount);
} }
double Cache::getAAT() double Cache::getAAT()
{ {
double HT = config.getHT(); double HT = config->getHT();
double MP = config.getMP(); double MP = config->getMP();
double MR = getMR(); double MR = getMR();
return HT + (MP * MR); return HT + (MP * MR);
} }
void Cache::Read() { r++; }
void Cache::ReadMiss() { rm++; } int Cache::getCommunication() { return readMiss + writeMiss + writeBack; }
void Cache::Write() { w++; }
void Cache::WriteMiss() { wm++; }
void Cache::WriteBack() { wb++; }
void Cache::Exchange() { ex++; }
int Cache::getCommunication() { return rm + wm + wb; }

View File

@ -10,12 +10,14 @@
using namespace std; using namespace std;
struct CacheIndex struct CacheIndex
{ {
uint32_t tag, index, offset, rAddr; uint32_t tag, index, offset, addr;
}; };
class CacheConfig class CacheConfig
{ {
public: public:
string level;
int blockSize; // Block Size int blockSize; // Block Size
int s; // Size int s; // Size
int assoc; // Assoc int assoc; // Assoc
@ -40,7 +42,7 @@ public:
uint32_t vim; // victim index mask uint32_t vim; // victim index mask
CacheConfig(); CacheConfig();
CacheConfig(int blockSize, int size, int ass, int vis, int rep, int wrp); CacheConfig(int blockSize, int size, int ass, int vis, int rep, int wrp, string l);
double getHT(); double getHT();
double getHT2(); double getHT2();
@ -63,46 +65,36 @@ public:
struct Block struct Block
{ {
uint32_t tag = 0; // tag uint32_t tag = 0;
uint32_t lru = 0; // Last Used uint32_t lru = 0; // Last Used
bool d = false; // dirty bool dirty = false;
bool v = false; // valid bool valid = false;
bool operator<(const Block &t) const { return lru < t.lru; } bool operator<(const Block &b) const { return lru < b.lru; }
}; };
class Cache class Cache
{ {
public: public:
CacheConfig config; CacheConfig *config;
vector<vector<Block>> c; // Cache vector<vector<Block>> cache;
vector<Block> vc; // Victim Cache vector<Block> victimCache;
string level; Cache *nextCache = nullptr;
Cache *NextCache = nullptr; int readCount = 0;
int readMiss = 0;
int writeCount = 0;
int writeMiss = 0;
int writeBack = 0;
int exchange = 0;
int r = 0; // Read Count
int rm = 0; // Read Miss
int w = 0; // Write Count
int wm = 0; // Write Miss
int wb = 0; // Write Back
int ex = 0; // Exchange (between L1 and Victim)
void Read();
void ReadMiss();
void Write();
void WriteMiss();
void WriteBack();
void Exchange();
int getCommunication(); int getCommunication();
double getMR(); double getMR();
double getMR2(); double getMR2();
double getAAT(); double getAAT();
Cache(CacheConfig *config, Cache *nextCache);
Cache(int blockSize, int s, int assoc, int victimSize, string l = "L1", int replicementPolicy = LRU, int writePolicy = LFU);
Cache(int blockSize, int s, int assoc, int victimSize, Cache *n = nullptr, string l = "L1", int replicementPolicy = LRU, int writePolicy = LFU);
void useCache(uint32_t rawAddr, bool isWrite); void useCache(uint32_t rawAddr, bool isWrite);
void printCache(); void printCache();
}; };

Binary file not shown.

Binary file not shown.

Binary file not shown.