本科在读,写着玩,然后顺便练了练语法(总之是很怪的代码),写了个FIFO的,LRU的,随机替换的,LFU的替换算法,有全相连,组相连,直接映射的cache模式,还有个三级cache,然后文件是需要自己拿gem5跑的(实验要求),然后测试cache命中率直接改前面的参数就好了,大概改改前面就能用?不能用的话我再改改(bushi)。
实际上少个LFU的组相连和直接映射,懒了不想写了,看着图一乐吧诸位()
#include<iostream>
#include<unordered_map>
#include<fstream>
#include<string>
#include<set>
using namespace std;
/* 替换算法模式 */
#define LRUMETHOD 1
#define FIFOMETHOD 2
#define LFUMETHOD 3
#define RANDOMMETHOD 4
/* Cache模式 */
#define ALLCONNECRED 111
#define GROUPCONNECRED 222
#define MAPDIRECT 333
/* 读取文件 */
#define FILENAME "matrix0.txt"
/* 随机数种子 */
#define RANDSEED 7
/* 请选择你的英雄,召唤师♂(取消注释即可) */
//#define LFU
//#define RANDOM
#define LRU
//#define FIFO
/* 请选择你的相连度,配合组相连效果更佳(和下面一起) */
#define GROUPCONNECTRITE 8
/* 组相连使能,如果使用组相连就注释掉 */
#define GROUPCONNCCETEDREG 0
/* 请选择你的Cache模式 */
#define MODE 111
/* 请选择你的Cache块属性 */
#define L1CAPACITY 32
#define L2CAPACITY 64
#define L3CAPACITY 128 // 这里有bug,不要某一级Cache不能设为0,建议和下面的blocksize都设置为1
#define L1BLOCKSIZE 4
#define L2BLOCKSIZE 8
#define L3BLOCKSIZE 16
#define L1INSCAPACITY 16
#define L1INSBLOCKSIZE 8
/* 随机数数组个数,Cache满了以后每miss一次用一个数 */
#define RANDOMNUMCAPACITY 1e8
class TreeNode {
public:
int Count, Time, Data;
TreeNode(int count, int time, int data) {
this->Count = count;
this->Time = time;
this->Data = data;
}
bool operator < (const TreeNode& treenode)const {
return Count == treenode.Count ? Time < treenode.Time : Count < treenode.Count;
}
};
class Node {
public:
int number;
Node* next, * prev;
public:
Node(int number, Node* next, Node* prev) {
this->number = number;
this->next = next;
this->prev = prev;
}
Node() :number(-1), next(nullptr), prev(nullptr) {}
};
class Queue {
public:
Node* front, * rear;
int size, full;
public:
Queue(int Capacity) {
front = rear = nullptr;
size = 0;
full = Capacity - 1;
}
void QueuePush(int num) {
if (size == 0)
front = rear = new Node(num, nullptr, nullptr);
else
rear->next = new Node(num, nullptr, nullptr);
size++;
}
Node* QueuePop() {
Node* result = front;
if (size == 1) front = rear = nullptr;
else front = front->next;
size--;
return front;
}
int getQueueSize() {
return this->size;
}
bool isQueueEmpty() {
return this->size == 0;
}
};
template<class T>
class AllConnectedCache {
public:
unordered_map<int, T*>cacheTableAll;
int CacheCapacityAll, sizeCacheAll, blockSizeAll;
Node* front, * rear;
int TimeForLFU;
set<TreeNode>LFURedBlackTree;
public:
AllConnectedCache(int CacheCapacity, int blockSize) {
this->front = new Node;
this->rear = new Node;
this->front->next = this->rear;
this->rear->prev = this->front;
this->CacheCapacityAll = CacheCapacity;
this->sizeCacheAll = 0;
this->blockSizeAll = blockSize;
this->TimeForLFU = 0;
}
void AllConnectedCachePushNode(int addr) {
Node* head = new Node(addr, nullptr, nullptr);
head->next = this->front->next;
head->prev = this->front;
head->next->prev = head;
this->front->next = head;
sizeCacheAll++;
cacheTableAll[addr] = head;
}
void AllConnectedCachePushTreeNode(int addr) {
TreeNode* node = new TreeNode(1, ++TimeForLFU, addr);
LFURedBlackTree.insert(*node);
sizeCacheAll++;
cacheTableAll[addr] = node;
}
virtual void AllConnectedCacheOverflow(int addr) = 0;
virtual void AllConnectedCacheInTable(int addr) = 0;
virtual void AllConnectedCachePush(int addr, int randNum = 1) = 0;
};
class GroupConnected {
public:
int eachCapacityCacheGroup, blockSizeGroup, setSizeGroup;
unordered_map<int, Node*> cacheTableGroup;
Node** NodeListFront;
Node** NodeListRear;
int* eachCacheSize;
GroupConnected(int eachCapacityCache, int blockSize, int setSize) {
this->eachCapacityCacheGroup = eachCapacityCache;
this->blockSizeGroup = blockSize;
NodeListFront = new Node * [setSize];
NodeListRear = new Node * [setSize];
eachCacheSize = new int[setSize]{ 0 };
this->setSizeGroup = setSize;
for (int i = 0; i < setSize; ++i) {
NodeListFront[i] = new Node;
NodeListRear[i] = new Node;
NodeListFront[i]->next = NodeListRear[i];
NodeListRear[i]->prev = NodeListFront[i];
}
}
void GroupConnectedCachePopRear(int setIndex) {
Node* deleteNode = NodeListRear[setIndex]->prev;
deleteNode->prev->next = deleteNode->next;
deleteNode->next->prev = deleteNode->prev;
cacheTableGroup.erase(deleteNode->number);
delete deleteNode;
--eachCacheSize[setIndex];
}
void GroupConnectedCachePopRand(int setIndex, int randNum) {
}
void GroupConnectedCacheMoveToHead(int addr) {
int setIndex = (addr / blockSizeGroup) % setSizeGroup;
Node* targetData = cacheTableGroup[addr];
targetData->next->prev = targetData->prev;
targetData->prev->next = targetData->next;
targetData->next = NodeListFront[setIndex]->next;
targetData->prev = NodeListFront[setIndex];
NodeListFront[setIndex]->next = targetData;
targetData->next->prev = targetData;
}
void GroupConnectedCachePush(int addr, int mode, int randNum = 0) {
int setIndex = (addr / blockSizeGroup) % setSizeGroup;
Node* head = new Node(addr, nullptr, nullptr);
head->next = NodeListFront[setIndex]->next;
head->prev = NodeListFront[setIndex];
NodeListFront[setIndex]->next->prev = head;
NodeListFront[setIndex]->next = head;
eachCacheSize[setIndex]++;
cacheTableGroup[addr] = head;
if (eachCacheSize[setIndex] > eachCapacityCacheGroup) {
switch (mode)
{
case LRUMETHOD: {
GroupConnectedCachePopRear(setIndex);
break;
}
case RANDOMMETHOD: {
GroupConnectedCachePopRand(setIndex, randNum);
break;
}
case FIFOMETHOD: {
GroupConnectedCachePopRear(setIndex);
break;
}
default:
break;
}
}
}
};
class MapDirect {
public:
int CapacityCacheMap, blockSizeMap;
int* Map;
MapDirect(int Capacity, int blockSize) :CapacityCacheMap(Capacity), blockSizeMap(blockSize) {
Map = new int[Capacity];
for (int i = 0; i < Capacity; ++i) Map[i] = -1;
}
bool MapDirectPush(int addr) {
addr = (addr / blockSizeMap);
if (Map[addr % CapacityCacheMap] != addr) {
Map[addr % CapacityCacheMap] = addr;
return false;
}
return true;
}
};
class LRUMethod : public AllConnectedCache<Node>, GroupConnected, MapDirect {
protected:
void AllConnectedCachePush(int addr, int randNum = 1) {
AllConnectedCachePushNode(addr);
if (sizeCacheAll > CacheCapacityAll)
AllConnectedCacheOverflow(addr);
}
void AllConnectedCacheOverflow(int addr) {
Node* deleteNode = rear->prev;
rear->prev = deleteNode->prev;
rear->prev->next = rear;
cacheTableAll.erase(deleteNode->number);
delete deleteNode;
--sizeCacheAll;
};
void AllConnectedCacheInTable(int addr) {
Node* targetData = cacheTableAll[addr];
targetData->next->prev = targetData->prev;
targetData->prev->next = targetData->next;
targetData->next = front->next;
targetData->prev = front;
front->next = targetData;
targetData->next->prev = targetData;
}
public:
LRUMethod(int CapacityCache, int blockSize, int setSize = 0) : AllConnectedCache(CapacityCache, blockSize), MapDirect(CapacityCache, blockSize), GroupConnected(CapacityCache, blockSize, setSize) { }
bool LRUCheckAllConnectedCache(int data) {
int addr = data - data % blockSizeAll;
if (!cacheTableAll.count(addr)) {
AllConnectedCachePush(addr);
return false;
}
else AllConnectedCacheInTable(addr);
return true;
}
bool LRUCheckMapDirectCache(int data) {
int addr = data - data % blockSizeMap;
return MapDirectPush(addr);
}
bool LRUCheckGroupConnectedCache(int data) {
int addr = data - data % blockSizeGroup;
if (!cacheTableGroup.count(addr)) {
GroupConnectedCachePush(addr, LRUMETHOD);
return false;
}
else GroupConnectedCacheMoveToHead(addr);
return true;
}
bool LRUCheck(int data, int mode) {
switch (mode)
{
case MAPDIRECT:
return LRUCheckMapDirectCache(data);
case ALLCONNECRED:
return LRUCheckAllConnectedCache(data);
case GROUPCONNECRED:
return LRUCheckGroupConnectedCache(data);
default:
break;
}
}
public:
int test() {
int arr[24] = { 2,8,2,4,8,2,6,9,7,8,6,1,8,4,2,3,7,5,9,8,7,4,2,3 };
int re = 0;
cout << "序列地址为:" << endl;
for (int i = 0; i < 24; ++i) {
cout << arr[i] << " ";
if (LRUCheckAllConnectedCache(arr[i])) {
re++;
}
}
cout << endl;
cout << endl;
return re;
}
};
class LFUMethod : public AllConnectedCache<TreeNode>, GroupConnected, MapDirect {
protected:
void AllConnectedCachePush(int addr, int randNum = 1) {
if (sizeCacheAll >= CacheCapacityAll)
AllConnectedCacheOverflow(addr);
AllConnectedCachePushTreeNode(addr);
}
void AllConnectedCacheOverflow(int addr) {
--sizeCacheAll;
cacheTableAll.erase(LFURedBlackTree.begin()->Data);
LFURedBlackTree.erase(LFURedBlackTree.begin());
}
void AllConnectedCacheInTable(int addr) {
auto iterator = cacheTableAll.find(addr);
TreeNode temp = *iterator->second;
LFURedBlackTree.erase(temp);
temp.Count++;
temp.Time = ++TimeForLFU;
temp.Data = addr;
LFURedBlackTree.insert(temp);
*iterator->second = temp;
}
public:
LFUMethod(int CapacityCache, int blockSize, int setSize = 0) : AllConnectedCache(CapacityCache, blockSize), MapDirect(CapacityCache, blockSize), GroupConnected(CapacityCache, blockSize, setSize) { }
bool LFUCheckAllConnectedCache(int data) {
int addr = data - data % blockSizeAll;
if (!cacheTableAll.count(addr)) {
AllConnectedCachePush(addr);
return false;
}
else AllConnectedCacheInTable(addr);
return true;
}
bool LFUCheck(int data, int mode) {
switch (mode)
{
case MAPDIRECT:
//return LFUCheckMapDirectCache(data);
case ALLCONNECRED:
return LFUCheckAllConnectedCache(data);
case GROUPCONNECRED:
//return FIFOCheckGroupConnectedCache(data);
default:
break;
}
}
int test() {
int arr[24] = { 2,8,2,4,8,2,6,9,7,8,6,1,8,4,2,3,7,5,9,8,7,4,2,3 };
int re = 0;
for (int i = 0; i < 24; ++i) {
if (LFUCheckAllConnectedCache(arr[i])) {
re++;
}
}
return re;
}
};
class RandomMethod : public AllConnectedCache<Node>, MapDirect {
private:
int* arr, index;
protected:
void AllConnectedCachePush(int addr, int randNum = 1) {
AllConnectedCachePushNode(addr);
if (sizeCacheAll > CacheCapacityAll)
AllConnectedCacheOverflow(randNum);
}
void AllConnectedCacheOverflow(int randNum) {
Node* head = front;
for (int i = 0; i <= randNum; ++i) head = head->next;
head->prev->next = head->next;
head->next->prev = head->prev;
cacheTableAll.erase(head->number);
delete head;
--sizeCacheAll;
}
void AllConnectedCacheInTable(int addr) { }
public:
RandomMethod(int capacityRandArr, int CacheCapacity, int blockSize) :AllConnectedCache(CacheCapacity, blockSize), MapDirect(CacheCapacity, blockSize) {
arr = new int[capacityRandArr];
srand(RANDSEED);
for (int i = 0; i < capacityRandArr; ++i) arr[i] = rand() % CacheCapacity;
index = 0;
}
bool RandomCheckAllConnectedCache(int data) {
int addr = data - data % blockSizeAll;
if (!cacheTableAll.count(addr)) {
while (arr[index] > sizeCacheAll) index++;
AllConnectedCachePush(data, arr[index++]);
return false;
}
return true;
}
bool RandomCheckMapDirectCache(int data) {
int addr = data - data % blockSizeMap;
return MapDirectPush(addr);
}
bool RandomCheck(int data, int mode) {
switch (mode)
{
case MAPDIRECT:
return RandomCheckMapDirectCache(data);
case ALLCONNECRED:
return RandomCheckAllConnectedCache(data);
case GROUPCONNECRED:
//return RandomCheckGroupConnectedCache(data);
default:
break;
}
}
int test() {
int arr[24] = { 2,8,2,4,8,2,6,9,7,8,6,1,8,4,2,3,7,5,9,8,7,4,2,3 };
int re = 0;
for (int i = 0; i < 24; ++i) {
if (RandomCheckAllConnectedCache(arr[i])) {
re++;
}
}
return re;
}
};
class FIFOMethod : public AllConnectedCache<Node>, GroupConnected, MapDirect {
protected:
void AllConnectedCachePush(int addr, int randNum = 1) {
AllConnectedCachePushNode(addr);
if (sizeCacheAll > CacheCapacityAll)
AllConnectedCacheOverflow(addr);
}
void AllConnectedCacheOverflow(int addr) {
Node* deleteNode = rear->prev;
rear->prev = deleteNode->prev;
rear->prev->next = rear;
cacheTableAll.erase(deleteNode->number);
delete deleteNode;
--sizeCacheAll;
}
void AllConnectedCacheInTable(int addr) {}
public:
FIFOMethod(int CacheCapacity, int blockSize, int setSize = 0) :AllConnectedCache(CacheCapacity, blockSize), MapDirect(CacheCapacity, blockSize), GroupConnected(CacheCapacity, blockSize, setSize) { }
bool FIFOCheckAllConnectedCache(int data) {
int addr = data - data % blockSizeAll;
if (!cacheTableAll.count(addr)) {
AllConnectedCachePush(addr);
return false;
}
return true;
}
bool FIFOCheckMapDirectCache(int data) {
int addr = data - data % blockSizeMap;
return MapDirectPush(addr);
}
bool FIFOCheckGroupConnectedCache(int data) {
int addr = data - data % blockSizeGroup;
if (!cacheTableGroup.count(addr)) {
GroupConnectedCachePush(addr, FIFOMETHOD);
return false;
}
return true;
}
bool FIFOCheck(int data, int mode) {
switch (mode)
{
case MAPDIRECT:
return FIFOCheckMapDirectCache(data);
case ALLCONNECRED:
return FIFOCheckAllConnectedCache(data);
case GROUPCONNECRED:
return FIFOCheckGroupConnectedCache(data);
default:
break;
}
}
public:
int test() {
int arr[24] = { 2,8,2,4,8,2,6,9,7,8,6,1,8,4,2,3,7,5,9,8,7,4,2,3 };
int re = 0;
for (int i = 0; i < 24; ++i) {
if (FIFOCheckAllConnectedCache(arr[i])) {
re++;
}
}
return re;
}
};
void CheckDataCacheLRUCopy(LRUMethod& LRUCacheL1, int addr, int mode, bool& tag) {
bool L1 = LRUCacheL1.LRUCheck(addr, mode);
tag &= L1;
}
bool CheckDataCacheLRU(LRUMethod& LRUCacheL1, LRUMethod& LRUCacheL2, LRUMethod& LRUCacheL3, int addr, int mode, int hitCacheLi[3]) {
bool L1 = LRUCacheL1.LRUCheck(addr, mode);
if (L1) {
hitCacheLi[0]++;
return true;
}
bool L2 = LRUCacheL2.LRUCheck(addr, mode);
if (L2) {
hitCacheLi[1]++;
return true;
}
bool L3 = LRUCacheL3.LRUCheck(addr, mode);
if (L3) {
hitCacheLi[2]++;
return true;
}
return false;
}
bool CheckInsCacheLRU(LRUMethod& LRUCacheL1, int addr, int mode) {
return LRUCacheL1.LRUCheck(addr, mode);
}
bool CheckDataCacheFIFO(FIFOMethod& LRUCacheL1, FIFOMethod& LRUCacheL2, FIFOMethod& LRUCacheL3, int addr, int mode, int hitCacheLi[3]) {
bool L1 = LRUCacheL1.FIFOCheck(addr, mode);
if (L1) {
hitCacheLi[0]++;
return true;
}
bool L2 = LRUCacheL2.FIFOCheck(addr, mode);
if (L2) {
hitCacheLi[1]++;
return true;
}
bool L3 = LRUCacheL3.FIFOCheck(addr, mode);
if (L3) {
hitCacheLi[2]++;
return true;
}
return false;
}
bool CheckInsCacheFIFO(FIFOMethod& LRUCacheL1, int addr, int mode) {
return LRUCacheL1.FIFOCheck(addr, mode);
}
bool CheckDataCacheRandom(RandomMethod& LRUCacheL1, RandomMethod& LRUCacheL2, RandomMethod& LRUCacheL3, int addr, int mode, int hitCacheLi[3]) {
bool L1 = LRUCacheL1.RandomCheck(addr, mode);
if (L1) {
hitCacheLi[0]++;
return true;
}
bool L2 = LRUCacheL2.RandomCheck(addr, mode);
if (L2) {
hitCacheLi[1]++;
return true;
}
bool L3 = LRUCacheL3.RandomCheck(addr, mode);
if (L3) {
hitCacheLi[2]++;
return true;
}
return false;
}
bool CheckInsCacheRandom(RandomMethod& LRUCacheL1, int addr) {
return LRUCacheL1.RandomCheckAllConnectedCache(addr);
}
bool CheckDataCacheLFU(LFUMethod& LRUCacheL1, LFUMethod& LRUCacheL2, LFUMethod& LRUCacheL3, int addr, int mode, int hitCacheLi[3]) {
bool L1 = LRUCacheL1.LFUCheck(addr, mode);
if (L1) {
hitCacheLi[0]++;
return true;
}
bool L2 = LRUCacheL2.LFUCheck(addr, mode);
if (L2) {
hitCacheLi[1]++;
return true;
}
bool L3 = LRUCacheL3.LFUCheck(addr, mode);
if (L3) {
hitCacheLi[2]++;
return true;
}
return false;
}
bool CheckInsCacheLFU(LFUMethod& LRUCacheL1, int addr, int mode) {
return LRUCacheL1.LFUCheck(addr, mode);
}
int hexStr2int(string str) {
int size = str.size(), flag = 0, re = 0;
for (int i = 0; i < size; ++i) {
if (flag) {
re = (re << 4);
re += (str[i] >= '0' && str[i] <= '9') ? (str[i] - '0') : (str[i] - 'a' + 10);
}
else if (str[i] == 'x') flag = 1;
}
return re;
}
int main() {
#ifdef GROUPCONNCCETEDREG
LRUMethod LRUCacheDataL1(L1CAPACITY, L1BLOCKSIZE);
LRUMethod LRUCacheDataL2(L2CAPACITY, L2BLOCKSIZE);
LRUMethod LRUCacheDataL3(L3CAPACITY, L3BLOCKSIZE);
LRUMethod LRUCacheInsL1(L1INSCAPACITY, L1INSBLOCKSIZE);
FIFOMethod FIFOCacheDataL1(L1CAPACITY, L1BLOCKSIZE);
FIFOMethod FIFOCacheDataL2(L2CAPACITY, L2BLOCKSIZE);
FIFOMethod FIFOCacheDataL3(L3CAPACITY, L3BLOCKSIZE);
FIFOMethod FIFOCacheInsL1(L1INSCAPACITY, L1INSBLOCKSIZE);
RandomMethod RandomCacheDataL1(RANDOMNUMCAPACITY, L1CAPACITY, L1BLOCKSIZE);
RandomMethod RandomCacheDataL2(RANDOMNUMCAPACITY, L2CAPACITY, L2BLOCKSIZE);
RandomMethod RandomCacheDataL3(RANDOMNUMCAPACITY, L3CAPACITY, L3BLOCKSIZE);
RandomMethod RandomCacheInsL1(RANDOMNUMCAPACITY, L1INSCAPACITY, L1INSBLOCKSIZE);
LFUMethod LFUCacheDataL1(L1CAPACITY, L1BLOCKSIZE);
LFUMethod LFUCacheDataL2(L2CAPACITY, L2BLOCKSIZE);
LFUMethod LFUCacheDataL3(L3CAPACITY, L3BLOCKSIZE);
LFUMethod LFUCacheInsL1(L1INSCAPACITY, L1INSBLOCKSIZE);
#else
LRUMethod LRUCacheDataL1(L1CAPACITY / GROUPCONNECTRITE, L1BLOCKSIZE, GROUPCONNECTRITE);
LRUMethod LRUCacheDataL2(L2CAPACITY / GROUPCONNECTRITE, L2BLOCKSIZE, GROUPCONNECTRITE);
LRUMethod LRUCacheDataL3(L3CAPACITY / GROUPCONNECTRITE, L3BLOCKSIZE, GROUPCONNECTRITE);
LRUMethod LRUCacheInsL1(L1INSCAPACITY / GROUPCONNECTRITE, L1INSBLOCKSIZE, GROUPCONNECTRITE);
FIFOMethod FIFOCacheDataL1(L1CAPACITY / GROUPCONNECTRITE, L1BLOCKSIZE, GROUPCONNECTRITE);
FIFOMethod FIFOCacheDataL2(L2CAPACITY / GROUPCONNECTRITE, L2BLOCKSIZE, GROUPCONNECTRITE);
FIFOMethod FIFOCacheDataL3(L3CAPACITY / GROUPCONNECTRITE, L3BLOCKSIZE, GROUPCONNECTRITE);
FIFOMethod FIFOCacheInsL1(L1INSCAPACITY / GROUPCONNECTRITE, L1INSBLOCKSIZE, GROUPCONNECTRITE);
RandomMethod RandomCacheDataL1(RANDOMNUMCAPACITY, L1CAPACITY, L1BLOCKSIZE);
RandomMethod RandomCacheDataL2(RANDOMNUMCAPACITY, L2CAPACITY, L2BLOCKSIZE);
RandomMethod RandomCacheDataL3(RANDOMNUMCAPACITY, L3CAPACITY, L3BLOCKSIZE);
RandomMethod RandomCacheInsL1(RANDOMNUMCAPACITY, L1INSCAPACITY, L1INSBLOCKSIZE);
LFUMethod LFUCacheDataL1(L1CAPACITY / GROUPCONNECTRITE, L1BLOCKSIZE, GROUPCONNECTRITE);
LFUMethod LFUCacheDataL2(L2CAPACITY / GROUPCONNECTRITE, L2BLOCKSIZE, GROUPCONNECTRITE);
LFUMethod LFUCacheDataL3(L3CAPACITY / GROUPCONNECTRITE, L3BLOCKSIZE, GROUPCONNECTRITE);
LFUMethod LFUCacheInsL1(L1INSCAPACITY / GROUPCONNECTRITE, L1INSBLOCKSIZE, GROUPCONNECTRITE);
#endif // !GROUPCONNECTEDREG
long long time_t = 0;
int hitDataLi[3]{ 0 }, hitIns = 0, totalData = 0, totalIns = 0, num = 0;
#ifdef FIFO
ifstream ifs;
ifs.open(FILENAME, ios::in);
string ins;
vector<int> strVec;
bool checkAllBool = true, tagL1 = true, tagL2 = true, tagL3 = true;
while (getline(ifs, ins)) {
int size = ins[0] - '0', i = 0;
strVec.resize(size, 0);
checkAllBool = tagL1 = tagL2 = tagL3 = true;
ins[0] = ifs.get();
if (ins[0] == '0') {
totalIns++;
for (int i = 0; i < size; ++i) {
getline(ifs, ins);
strVec[i] = hexStr2int(ins);
checkAllBool &= CheckInsCacheFIFO(FIFOCacheInsL1, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheFIFO(FIFOCacheDataL2, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheFIFO(FIFOCacheDataL3, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
}
else {
totalData++;
for (int i = 0; i < size; ++i) {
getline(ifs, ins);
strVec[i] = hexStr2int(ins);
tagL1 &= CheckInsCacheFIFO(FIFOCacheDataL1, strVec[i], MODE);
time_t += 1;
}
hitDataLi[0] += tagL1 ? 1 : 0;
if (tagL1) continue;
for (int i = 0; i < size; ++i) {
tagL2 &= CheckInsCacheFIFO(FIFOCacheDataL2, strVec[i], MODE);
time_t += 10;
}
hitDataLi[1] += tagL2 ? 1 : 0;
if (tagL2) continue;
for (int i = 0; i < size; ++i) {
tagL3 &= CheckInsCacheFIFO(FIFOCacheDataL3, strVec[i], MODE);
time_t += 100;
}
hitDataLi[2] += tagL3 ? 1 : 0;
if (tagL3) continue;
time_t += 1000;
}
}
#endif
#ifdef LRU
ifstream ifs;
ifs.open(FILENAME, ios::in);
string ins;
vector<int> strVec;
bool checkAllBool = true, tagL1 = true, tagL2 = true, tagL3 = true;
while (getline(ifs, ins)) {
int size = ins[0] - '0', i = 0;
strVec.resize(size, 0);
checkAllBool = tagL1 = tagL2 = tagL3 = true;
ins[0] = ifs.get();
if (ins[0] == '0') {
totalIns++;
for (int i = 0; i < size; ++i) {
getline(ifs, ins);
strVec[i] = hexStr2int(ins);
checkAllBool &= CheckInsCacheLRU(LRUCacheInsL1, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheLRU(LRUCacheDataL2, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheLRU(LRUCacheDataL3, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
}
else {
totalData++;
for (int i = 0; i < size; ++i) {
getline(ifs, ins);
strVec[i] = hexStr2int(ins);
time_t += 1;
tagL1 &= CheckInsCacheLRU(LRUCacheDataL1, strVec[i], MODE);
}
hitDataLi[0] += tagL1 ? 1 : 0;
if (tagL1) continue;
for (int i = 0; i < size; ++i) {
tagL2 &= CheckInsCacheLRU(LRUCacheDataL2, strVec[i], MODE);
time_t += 10;
}
hitDataLi[1] += tagL2 ? 1 : 0;
if (tagL2) continue;
for (int i = 0; i < size; ++i) {
tagL3 &= CheckInsCacheLRU(LRUCacheDataL3, strVec[i], MODE);
time_t += 100;
}
hitDataLi[2] += tagL3 ? 1 : 0;
if (tagL3) continue;
time_t += 1000;
}
}
#endif
#ifdef RANDOM
ifstream ifs;
ifs.open(FILENAME, ios::in);
string ins;
vector<string> strVec;
bool checkAllBool = true, tagL1 = true, tagL2 = true, tagL3 = true;
while (getline(ifs, ins)) {
int size = ins[0] - '0', i = 0;
strVec.resize(size, "");
checkAllBool = tagL1 = tagL2 = tagL3 = true;
ins[0] = ifs.get();
if (ins[0] == '0') {
totalIns++;
for (int i = 0; i < size; ++i) {
getline(ifs, strVec[i]);
checkAllBool &= CheckInsCacheRandom(RandomCacheInsL1, hexStr2int(strVec[i]));
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheRandom(RandomCacheDataL2, hexStr2int(strVec[i]));
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheRandom(RandomCacheDataL3, hexStr2int(strVec[i]));
}
hitIns += checkAllBool == 1 ? 1 : 0;
}
else {
totalData++;
for (int i = 0; i < size; ++i) {
getline(ifs, strVec[i]);
time_t += 1;
tagL1 &= CheckInsCacheRandom(RandomCacheDataL1, hexStr2int(strVec[i]));
}
hitDataLi[0] += tagL1 ? 1 : 0;
if (tagL1) continue;
for (int i = 0; i < size; ++i) {
tagL2 &= CheckInsCacheRandom(RandomCacheDataL2, hexStr2int(strVec[i]));
time_t += 10;
}
hitDataLi[1] += tagL2 ? 1 : 0;
if (tagL2) continue;
for (int i = 0; i < size; ++i) {
tagL3 &= CheckInsCacheRandom(RandomCacheDataL3, hexStr2int(strVec[i]));
time_t += 100;
}
hitDataLi[2] += tagL3 ? 1 : 0;
if (tagL3) continue;
time_t += 1000;
}
}
#endif
#ifdef LFU
ifstream ifs;
ifs.open(FILENAME, ios::in);
string ins;
vector<int> strVec;
bool checkAllBool = true, tagL1 = true, tagL2 = true, tagL3 = true;
while (getline(ifs, ins)) {
int size = ins[0] - '0', i = 0;
strVec.resize(size, 0);
checkAllBool = tagL1 = tagL2 = tagL3 = true;
ins[0] = ifs.get();
if (ins[0] == '0') {
totalIns++;
for (int i = 0; i < size; ++i) {
getline(ifs, ins);
strVec[i] = hexStr2int(ins);
checkAllBool &= CheckInsCacheLFU(LFUCacheInsL1, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheLFU(LFUCacheDataL2, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
if (checkAllBool) continue;
checkAllBool = true;
for (int i = 0; i < size; ++i) {
checkAllBool &= CheckInsCacheLFU(LFUCacheDataL3, strVec[i], MODE);
}
hitIns += checkAllBool == 1 ? 1 : 0;
}
else {
totalData++;
for (int i = 0; i < size; ++i) {
getline(ifs, ins);
strVec[i] = hexStr2int(ins);
time_t += 1;
tagL1 &= CheckInsCacheLFU(LFUCacheDataL1, strVec[i], MODE);
}
hitDataLi[0] += tagL1 ? 1 : 0;
if (tagL1) continue;
for (int i = 0; i < size; ++i) {
tagL2 &= CheckInsCacheLFU(LFUCacheDataL2, strVec[i], MODE);
time_t += 10;
}
hitDataLi[1] += tagL2 ? 1 : 0;
if (tagL2) continue;
for (int i = 0; i < size; ++i) {
tagL3 &= CheckInsCacheLFU(LFUCacheDataL3, strVec[i], MODE);
time_t += 100;
}
hitDataLi[2] += tagL3 ? 1 : 0;
if (tagL3) continue;
time_t += 1000;
}
}
#endif
/*
LRUMethod LRUTest(3, 2, 2);
cout << "LRU、全相联算法下,容量为3,块大小为2时,命中次数为:" << LRUTest.test() << endl;
FIFOMethod FIFOTest(3, 2, 2);
cout << "FIFO、全相联算法下,容量为3,块大小为2时,命中次数为:" << FIFOTest.test() << endl;
LFUMethod LFUTest(3, 2, 2);
cout << "LFU、全相联算法下,容量为3,块大小为2时,命中次数为:" << LFUTest.test() << endl;
*/
cout << "第一级Cache的命中率为:" << (double)hitDataLi[0] / totalData * 100 << "%\n第二级Cache的命中率为:" << (double)hitDataLi[1] / totalData * 100 << "%\n第三级Cache的命中率为:" << (double)hitDataLi[2] / totalData * 100 << "%\nCache总命中率为:" << ((double)hitDataLi[0] + (double)hitDataLi[1] + (double)hitDataLi[2]) / totalData * 100 << "%" << endl;
cout << "\n指令Cache命中率为" << (double)hitIns / totalIns * 100 << "%" << endl;
cout << "\n查找数据总耗时为" << time_t << "ns" << endl;
return 0;
}