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

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

Binary file not shown.

View File

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

View File

@ -10,12 +10,14 @@
using namespace std;
struct CacheIndex
{
uint32_t tag, index, offset, rAddr;
uint32_t tag, index, offset, addr;
};
class CacheConfig
{
public:
string level;
int blockSize; // Block Size
int s; // Size
int assoc; // Assoc
@ -40,7 +42,7 @@ public:
uint32_t vim; // victim index mask
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 getHT2();
@ -63,46 +65,36 @@ public:
struct Block
{
uint32_t tag = 0; // tag
uint32_t tag = 0;
uint32_t lru = 0; // Last Used
bool d = false; // dirty
bool v = false; // valid
bool operator<(const Block &t) const { return lru < t.lru; }
bool dirty = false;
bool valid = false;
bool operator<(const Block &b) const { return lru < b.lru; }
};
class Cache
{
public:
CacheConfig config;
CacheConfig *config;
vector<vector<Block>> c; // Cache
vector<Block> vc; // Victim Cache
string level;
vector<vector<Block>> cache;
vector<Block> victimCache;
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();
double getMR();
double getMR2();
double getAAT();
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);
Cache(CacheConfig *config, Cache *nextCache);
void useCache(uint32_t rawAddr, bool isWrite);
void printCache();
};

Binary file not shown.

Binary file not shown.

Binary file not shown.