RTSA-lab01-CacheAnalysis/include/AbstractState.h

273 lines
7.3 KiB
C
Raw Normal View History

2022-04-19 10:56:42 +02:00
#ifndef ABSSTATE_H
#define ABSSTATE_H
#include <algorithm>
2022-04-19 10:56:42 +02:00
#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <list>
#include <map>
#include <ostream>
#include <sstream>
#include <string>
#include <llvm/Support/raw_ostream.h>
2022-04-19 10:56:42 +02:00
#include "Address.h"
// Forward declarations
namespace cacheAnaPass {
class AbstractState;
} // namespace cacheAnaPass
class AbstractState {
public: // everything is public, because IDGAF
std::list<unsigned int> Successors;
std::list<unsigned int> Predecessors;
unsigned int Addr;
2022-04-29 14:31:08 +02:00
unsigned int Unrolled;
2022-04-19 10:56:42 +02:00
2022-05-06 10:04:45 +02:00
int Computed = 0;
bool Filled = false;
2022-04-19 10:56:42 +02:00
// Only entries below this comment are needed for the exercise.
/**
* @brief Containing all Abstract Cache Tags.
* Key of the list has no Meaning.
*
*/
struct Entry {
std::list<unsigned int> Blocks;
};
/**
* @brief Cache Set, Key is the Age of the Entries.
*
*/
struct Set {
// uInt in this map is the Age.
std::map<unsigned int, Entry> Associativity;
};
/**
* @brief Cache Sets, key is the Set number [0-15], derived from Address.
*
*/
std::map<unsigned int, Set> Sets;
AbstractState(AbstractState const &Copy) {
2022-04-29 14:31:08 +02:00
Addr = Copy.Addr;
Unrolled = Copy.Unrolled;
2022-04-19 10:56:42 +02:00
for (auto S : Copy.Sets) {
unsigned int SetNr = S.first;
for (auto E : S.second.Associativity) {
unsigned int Age = E.first;
for (auto B : E.second.Blocks) {
Sets[SetNr].Associativity[Age].Blocks.push_back(B);
}
}
}
}
AbstractState(AbstractState const &Copy, Address Update) {
Addr = Copy.Addr;
Unrolled = Copy.Unrolled;
for (auto S : Copy.Sets) {
unsigned int SetNr = S.first;
for (auto E : S.second.Associativity) {
unsigned int Age = E.first;
for (auto B : E.second.Blocks) {
Sets[SetNr].Associativity[Age].Blocks.push_back(B);
}
}
}
this->update(Update);
}
2022-04-19 10:56:42 +02:00
AbstractState() {}
2022-04-29 14:31:08 +02:00
AbstractState(unsigned int AddressIn) {
Addr = AddressIn;
Unrolled = 0;
}
2022-04-19 10:56:42 +02:00
2022-04-29 14:31:08 +02:00
AbstractState(unsigned int AddressIn, unsigned int UnrolledIn) {
Addr = AddressIn;
Unrolled = UnrolledIn;
2022-04-20 13:36:41 +02:00
}
2022-04-19 10:56:42 +02:00
2022-04-29 14:31:08 +02:00
void setUnrolled(unsigned int In) { Unrolled = In; }
bool operator==(AbstractState In) {
for (int Index; Index < 16; Index++) {
for (int Age; Age < 4; Age++) {
for (auto E1 : Sets[Index].Associativity[Age].Blocks) {
// find E1 in In States Set and Age.
if (std::find(In.Sets[Index].Associativity[Age].Blocks.begin(),
In.Sets[Index].Associativity[Age].Blocks.end(),
E1) == In.Sets[Index].Associativity[Age].Blocks.end()) {
return false;
}
}
for (auto E2 : In.Sets[Index].Associativity[Age].Blocks) {
// find E2 in This Set and Age.
if (std::find(Sets[Index].Associativity[Age].Blocks.begin(),
Sets[Index].Associativity[Age].Blocks.end(),
E2) == Sets[Index].Associativity[Age].Blocks.end()) {
return false;
}
}
}
}
return true;
}
2022-04-19 10:56:42 +02:00
/**
* @brief Executes an Must LRU Join on the AbstractCacheState
*
* @param In, AbstractState that gets joined into the State.
*/
void mustJoin(AbstractState In) {
2022-04-20 13:36:41 +02:00
/**
* The exercise is to Fill this function with an LRU must Join.
* For this you need to use Sets. Associativity and Blocks.
*/
2022-05-24 21:53:15 +02:00
// TODO: Due date 08.06.2022
// Loop through all 16 sets
for (int Index; Index < 16; Index++) {
// create a temporary set of associativity
struct Set temp_set;
// loop through all 4 Ages
for (int Age; Age < 4; Age++) {
struct Set current_set = Sets[Index];
struct Set incoming_set = In.Sets[Index];
// loop through current set and build list of all contained blocks
for (auto age: current_set.Associativity) {
std::cout << age.first
<< ":";
for (auto block : age.second.Blocks)
std::cout << block << std::endl;
}
// loop through incoming set and build list of all contained blocks
for (auto E2 : In.Sets[Index].Associativity[Age].Blocks) {
}
}
Sets[Index] = temp_set;
}
2022-04-19 10:56:42 +02:00
}
2022-04-20 13:36:41 +02:00
/**
2022-04-19 10:56:42 +02:00
* @brief Checks if Address Addr is in Cache
*
* @param Addr Address to check.
* @return true CacheState contains Address Addr
* @return false CacheState does not contain Address Addr
*/
bool isHit(Address Addr) {
for (auto E : Sets[Addr.Index].Associativity) {
for (auto B : E.second.Blocks) {
if (B == Addr.Tag)
return true;
}
}
return false;
}
/**
* @brief Updates the AbstractState with given Address
*
* @param Addr , Address
*/
void update(Address Addr) {
2022-05-06 10:04:45 +02:00
// If Updated Address is of Age 0 do nothing
if (std::find(Sets[Addr.Index].Associativity[0].Blocks.begin(),
Sets[Addr.Index].Associativity[0].Blocks.end(),
Addr.Tag) != Sets[Addr.Index].Associativity[0].Blocks.end())
return;
2022-04-29 14:31:08 +02:00
// This loopages all entries by one. 3 <-2, 2<-1, 1<-0
for (int I = 3; I > 0; I--) {
Sets[Addr.Index].Associativity[I] = Sets[Addr.Index].Associativity[I - 1];
Sets[Addr.Index].Associativity[I].Blocks.remove(Addr.Tag);
2022-04-19 10:56:42 +02:00
}
2022-04-29 14:31:08 +02:00
// entry at age 0 is updated with current address.
2022-04-19 10:56:42 +02:00
Sets[Addr.Index].Associativity[0].Blocks = {Addr.Tag};
}
/**
2022-04-29 14:31:08 +02:00
* @brief Fills the AbstractState PreState and updates with PreAddress.
2022-04-19 10:56:42 +02:00
*
* @param PreState, State that fills this state.
*
* @param PreAddr Address of PreState
*/
void fill(AbstractState PreState, Address PreAddr) {
2022-05-06 10:04:45 +02:00
bool Verbose = false;
2022-04-29 14:31:08 +02:00
// copy Pre State into this.
2022-04-19 10:56:42 +02:00
for (auto S : PreState.Sets) {
unsigned int Index = S.first;
for (auto E : S.second.Associativity) {
2022-04-29 14:31:08 +02:00
unsigned int Age = E.first;
2022-04-19 10:56:42 +02:00
// If updated age is greater 4 The Tag is no longer in Cache.
// Due to associativity of 4 per set.
if (Age >= 4)
break;
for (auto B : E.second.Blocks) {
Sets[Index].Associativity[Age].Blocks.push_back(B);
}
}
}
2022-05-06 10:04:45 +02:00
if (Verbose) {
llvm::outs() << "Before:\n";
this->dump();
}
2022-04-29 14:31:08 +02:00
// update this with PreAddr
this->update(PreAddr);
2022-05-06 10:04:45 +02:00
if (Verbose) {
llvm::outs() << "Update Tag: " << PreAddr.Tag << "\n";
llvm::outs() << "Update Set: " << PreAddr.Index << "\n";
llvm::outs() << "After:\n";
this->dump();
}
2022-04-19 10:56:42 +02:00
}
void dump() {
llvm::outs() << Addr << " {\n";
2022-04-29 14:31:08 +02:00
llvm::outs() << "Unrolled: " << Unrolled << "\n";
2022-05-06 10:04:45 +02:00
llvm::outs() << "Computed: " << Computed << "\n";
2022-04-19 10:56:42 +02:00
llvm::outs() << "Predecessors: ";
for (auto PreNr : Predecessors) {
llvm::outs() << PreNr << " ";
}
llvm::outs() << "\n";
llvm::outs() << "Successors: ";
for (auto SuccNr : Successors) {
llvm::outs() << SuccNr << " ";
}
llvm::outs() << "\n";
for (auto SetPair : Sets) {
llvm::outs() << "Set[" << SetPair.first << "]: \n";
for (auto EntryPair : SetPair.second.Associativity) {
llvm::outs() << " Age[" << EntryPair.first << "]: ";
for (auto Block : EntryPair.second.Blocks) {
llvm::outs() << Block << " ";
}
llvm::outs() << "\n";
}
}
llvm::outs() << "}\n";
}
}; // namespace
#endif // STATE_H