关于软件实现cache的课程作业

本科在读,写着玩,然后顺便练了练语法(总之是很怪的代码),写了个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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值