Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Cache Replacement Policy #335

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 66 additions & 19 deletions src/cachesim/cachegraphic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,47 @@ void CacheGraphic::updateLineReplFields(unsigned lineIdx) {
return;
}

if (m_cacheTextItems.at(0).at(0).lru == nullptr) {
if (m_cacheTextItems.at(0).at(0).lru == nullptr && m_cache.getReplacementPolicy() == ReplPolicy::LRU) {
// The current cache configuration does not have any replacement field
return;
}

for (const auto &way : m_cacheTextItems[lineIdx]) {
// If LRU was just initialized, the actual (software) LRU value may be very
// large. Mask to the number of actual LRU bits.
unsigned lruVal = cacheLine->at(way.first).lru;
lruVal &= vsrtl::generateBitmask(m_cache.getWaysBits());
const QString lruText = QString::number(lruVal);
way.second.lru->setText(lruText);

// LRU text might have changed; update LRU field position to center in
// column
const qreal y = lineIdx * m_lineHeight + way.first * m_setHeight;
const qreal x =
m_widthBeforeLRU + m_lruWidth / 2 - m_fm.horizontalAdvance(lruText) / 2;

way.second.lru->setPos(x, y);
if (m_cacheTextItems.at(0).at(0).fifo == nullptr && m_cache.getReplacementPolicy() == ReplPolicy::FIFO){
return;
}
if(m_cache.getReplacementPolicy() == ReplPolicy::LRU){
for (const auto &way : m_cacheTextItems[lineIdx]) {
// If LRU was just initialized, the actual (software) LRU value may be very
// large. Mask to the number of actual LRU bits.
unsigned lruVal = cacheLine->at(way.first).lru;
lruVal &= vsrtl::generateBitmask(m_cache.getWaysBits());
const QString lruText = QString::number(lruVal);
way.second.lru->setText(lruText);

// LRU text might have changed; update LRU field position to center in
// column
const qreal y = lineIdx * m_lineHeight + way.first * m_setHeight;
const qreal x =
m_widthBeforeLRU + m_lruWidth / 2 - m_fm.horizontalAdvance(lruText) / 2;
way.second.lru->setPos(x, y);
}
}
if(m_cache.getReplacementPolicy() == ReplPolicy::FIFO){
for (const auto &way : m_cacheTextItems[lineIdx]) {
// If LRU was just initialized, the actual (software) LRU value may be very
// large. Mask to the number of actual LRU bits.
int fifoVal = cacheLine->at(way.first).fifo;
const QString fifoText = QString::number(fifoVal);
way.second.fifo->setText(fifoText);

// LRU text might have changed; update LRU field position to center in
// column
const qreal y = lineIdx * m_lineHeight + way.first * m_setHeight;
const qreal x =
m_widthBeforefifo + m_fifoWidth / 2 - m_fm.horizontalAdvance(fifoText) / 2;
way.second.fifo->setPos(x, y);
}
Comment on lines +108 to +139
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LRU and FIFO code here is now essentially identical - please think about how to reduce code duplication here.

}

}

QString CacheGraphic::addressString() const {
Expand Down Expand Up @@ -409,6 +429,7 @@ void CacheGraphic::cacheInvalidated() {
m_blockWidth = m_fm.horizontalAdvance(" " + addressString() + " ");
m_bitWidth = m_fm.horizontalAdvance("00");
m_lruWidth = m_fm.horizontalAdvance(QString::number(m_cache.getWays()) + " ");
m_fifoWidth = m_fm.horizontalAdvance(QString::number(m_cache.getWays()) + " ");
m_cacheHeight = m_lineHeight * m_cache.getLines();
m_tagWidth = m_blockWidth;

Expand Down Expand Up @@ -436,9 +457,10 @@ void CacheGraphic::cacheInvalidated() {
}

m_widthBeforeLRU = width;
m_widthBeforefifo = width;

if (m_cache.getReplacementPolicy() == ReplPolicy::LRU &&
m_cache.getWays() > 1) {
if (m_cache.getReplacementPolicy() == ReplPolicy::LRU
&& m_cache.getWays() > 1) {
// Draw LRU bit column
new QGraphicsLineItem(width + m_lruWidth, 0, width + m_lruWidth,
m_cacheHeight, this);
Expand All @@ -451,6 +473,23 @@ void CacheGraphic::cacheInvalidated() {
width += m_lruWidth;
}


if (m_cache.getReplacementPolicy() == ReplPolicy::FIFO
&& m_cache.getWays() > 1) {
// Draw FIFO bit column
new QGraphicsLineItem(width + m_fifoWidth, 0, width + m_fifoWidth,
m_cacheHeight, this);
const QString fifoBitText = "FIFO";
auto *textItem = drawText(fifoBitText,
width + m_fifoWidth / 2 -
m_fm.horizontalAdvance(fifoBitText) / 2,
-m_fm.height());
textItem->setToolTip("FIFO bits");
width += m_fifoWidth;
}



m_widthBeforeTag = width;

// Draw tag column
Expand Down Expand Up @@ -705,6 +744,14 @@ void CacheGraphic::initializeControlBits() {
m_fm.horizontalAdvance(lruText) / 2;
line[setIdx].lru = drawText(lruText, x, y);
}
if (m_cache.getReplacementPolicy() == ReplPolicy::FIFO &&
m_cache.getWays() > 1) {
const QString fifoText = QString::number(0);
x = m_widthBeforefifo + m_fifoWidth / 2 -
m_fm.horizontalAdvance(fifoText) / 2;
Comment on lines +750 to +751
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to just do m_fm.horizontalAdvance(QStringLiteral("0"))

// Create FIFO field
line[setIdx].fifo = drawText("0", x, y);
}
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/cachesim/cachegraphic.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public slots:
std::map<unsigned, std::unique_ptr<QGraphicsSimpleTextItem>> blocks;
std::unique_ptr<QGraphicsSimpleTextItem> tag = nullptr;
QGraphicsSimpleTextItem *lru = nullptr;
QGraphicsSimpleTextItem *fifo = nullptr;
QGraphicsSimpleTextItem *valid = nullptr;
QGraphicsSimpleTextItem *dirty = nullptr;
std::map<unsigned, std::unique_ptr<QGraphicsRectItem>> dirtyBlocks;
Expand Down Expand Up @@ -113,9 +114,10 @@ public slots:
qreal m_widthBeforeBlocks = 0;
qreal m_widthBeforeTag = 0;
qreal m_widthBeforeLRU = 0;
qreal m_widthBeforefifo = 0;
qreal m_widthBeforeDirty = 0;
qreal m_lruWidth = 0;

qreal m_fifoWidth = 0;
static constexpr qreal z_grid = 0;
static constexpr qreal z_wires = -1;

Expand Down
71 changes: 67 additions & 4 deletions src/cachesim/cachesim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ void CacheSim::updateCacheLineReplFields(CacheLine &line, unsigned wayIdx) {
// Upgrade @p lruIdx to the most recently used
line[wayIdx].lru = 0;
}

if (getReplacementPolicy() == ReplPolicy::FIFO) {
for(auto &set : line){
if(m_fifoflag && set.second.valid){
set.second.fifo ++;
}
}
m_fifoflag = false;
}
}

void CacheSim::revertCacheLineReplFields(CacheLine &line,
Expand All @@ -69,6 +78,15 @@ void CacheSim::revertCacheLineReplFields(CacheLine &line,
// Revert the oldWay LRU
line[wayIdx].lru = oldWay.lru;
}

if (getReplacementPolicy() == ReplPolicy::FIFO) {

for(auto &set : line){
if(set.second.valid && m_fifoflag) set.second.fifo--;
}
m_fifoflag = false;
line[wayIdx].fifo = oldWay.fifo;
}
}

CacheSim::CacheSize CacheSim::getCacheSize() const {
Expand All @@ -95,6 +113,13 @@ CacheSim::CacheSize CacheSim::getCacheSize() const {
size.bits += componentBits;
}

if (m_replPolicy == ReplPolicy::FIFO) {
// FIFO bits
componentBits = getWaysBits() * entries;
size.components.push_back("FIFO bits: " + QString::number(componentBits));
size.bits += componentBits;
}

// Tag bits
componentBits = vsrtl::bitcount(m_tagMask) * entries;
size.components.push_back("Tag bits: " + QString::number(componentBits));
Expand All @@ -115,13 +140,48 @@ CacheSim::locateEvictionWay(const CacheTransaction &transaction) {
std::pair<unsigned, CacheSim::CacheWay *> ew;
ew.first = s_invalidIndex;
ew.second = nullptr;

// Locate a new way based on replacement policy.
if (m_replPolicy == ReplPolicy::Random) {
// Select a random way
ew.first = std::rand() % getWays();
ew.second = &cacheLine[ew.first];
} else if (m_replPolicy == ReplPolicy::LRU) {
}
else if (m_replPolicy == ReplPolicy::FIFO){
// ew.first = m_fifoIndexCounter;
// ew.second = &cacheLine[ew.first];
// m_fifoIndexCounter += 1;
// m_fifoIndexCounter %= getWays();
Comment on lines +150 to +153
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented out code

if (getWays() == 1) {
// Nothing to do if we are in LRU and only have 1 set.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a comment about LRU when we're in FIFO replacement policy?

ew.first = 0;
ew.second = &cacheLine[ew.first];
} else {
// Lazily initialize all ways in the cacheline before starting to iterate.
for (int i = 0; i < getWays(); ++i)
cacheLine[i];

// If there is an invalid cache line, select that.
auto it =
std::find_if(cacheLine.begin(), cacheLine.end(),
[=](const auto &way) { return !way.second.valid; });
if (it != cacheLine.end()) {
ew.first = it->first;
ew.second = &it->second;
m_fifoflag = true;
}
if (ew.second == nullptr) {
for (auto &way : cacheLine) {
if (static_cast<long>(way.second.fifo) == getWays()){
ew.first = way.first;
ew.second = &way.second;
m_fifoflag = true;
break;
}
}
}
}
}
else if (m_replPolicy == ReplPolicy::LRU) {
if (getWays() == 1) {
// Nothing to do if we are in LRU and only have 1 set.
ew.first = 0;
Expand Down Expand Up @@ -150,8 +210,7 @@ CacheSim::locateEvictionWay(const CacheTransaction &transaction) {
}
}
}
}

}
Q_ASSERT(ew.first != s_invalidIndex && "Unable to locate way for eviction");
Q_ASSERT(ew.second != nullptr && "Unable to locate way for eviction");
return ew;
Expand Down Expand Up @@ -380,6 +439,10 @@ void CacheSim::undo() {
else if (!trace.transaction.isHit) {
way = oldWay;
}
if (!trace.transaction.isHit && getReplacementPolicy() == ReplPolicy::FIFO) {
m_fifoflag = true;
way = oldWay;
}
// Case 3: Else, it was a cache hit; Revert replacement fields and dirty
// blocks
way.dirtyBlocks = oldWay.dirtyBlocks;
Expand Down
8 changes: 5 additions & 3 deletions src/cachesim/cachesim.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class CacheSim;

enum WriteAllocPolicy { WriteAllocate, NoWriteAllocate };
enum WritePolicy { WriteThrough, WriteBack };
enum ReplPolicy { Random, LRU };
enum ReplPolicy { Random, LRU, FIFO };

struct CachePreset {
QString name;
Expand Down Expand Up @@ -91,7 +91,8 @@ class CacheSim : public CacheInterface {
Q_OBJECT
public:
static constexpr unsigned s_invalidIndex = static_cast<unsigned>(-1);

unsigned m_fifoIndexCounter = 0;
bool m_fifoflag = false;
struct CacheSize {
unsigned bits = 0;
std::vector<QString> components;
Expand All @@ -106,6 +107,7 @@ class CacheSim : public CacheInterface {
// LRU algorithm relies on invalid cache ways to have an initial high value.
// -1 ensures maximum value for all way sizes.
unsigned lru = -1;
int fifo = 0;
};

struct CacheIndex {
Expand Down Expand Up @@ -329,7 +331,7 @@ public slots:
};

const static std::map<ReplPolicy, QString> s_cacheReplPolicyStrings{
{ReplPolicy::Random, "Random"}, {ReplPolicy::LRU, "LRU"}};
{ReplPolicy::Random, "Random"}, {ReplPolicy::LRU, "LRU"}, {ReplPolicy::FIFO, "FIFO"}};
const static std::map<WriteAllocPolicy, QString> s_cacheWriteAllocateStrings{
{WriteAllocPolicy::WriteAllocate, "Write allocate"},
{WriteAllocPolicy::NoWriteAllocate, "No write allocate"}};
Expand Down