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

Conversation

tinhanho
Copy link

@tinhanho tinhanho commented Dec 24, 2023

About Issue #334.

I think that we could add a FIFO mechanism to the cache policy.

A new replacement policy, FIFO (First In, First Out), has been added to the existing enumeration. Additionally, a new counter has been introduced in the cachesim.h file. This counter plays a crucial role in cyclically determining which cache entry should be evicted.

// line 19 in cachesim.h
enum ReplPolicy { Random, LRU, FIFO}; 

The code below handles the eviction process based on the FIFO replacement policy.

//line 124 in cachesim.cpp
else if (m_replPolicy == ReplPolicy::FIFO){
    ew.first = CacheSim::counter;
    ew.second = &cacheLine[ew.first];
    CacheSim::counter += 1;
CacheSim::counter %= getWays();
}

Add Policy FIFO for cache replacement.
@mortbopet
Copy link
Owner

Thank you for looking into adding a new cache replacement policy!

A few comments:

  • As per the coding style currently used in Ripes, member variables should be prefixed with m_ and not with the class name.
  • I think the counter should be named better, e.g. fifoIndexCounter.
  • (optional) do you think there is an accompanying visualization to this? i.e., for LRU, we also show the LRU bits. Could one imagine a similar column which indicates what way in the cache line is currently up for eviction as per. FIFO?

Refer to author's comment. Rename counter and edit prefix.
@tinhanho
Copy link
Author

tinhanho commented Jan 2, 2024

Hi, @mortbopet.

Thanks for the reply. I had already renamed the counter and tried my best to follow the coding style. If there are any problem still, please let me know.

As for third comments, I rework all the framework to implement visualizing the FIFO bit. Now, there is no need about fifoIndexCounter. Instead, boolean fifoflag is presented. This flag is set under two circumstances,

  1. When an invalid entry is selected, we set the fifoflag.
  2. When all the entries are full and cache miss occurs, we need to choose a entry to evicted and we set the fifoflag.

When this flag is set, we shall add 1 to fifo bits if entry is valid. In this way, we'll find that when fifo bits equal to the way of the cache, that entry should be evicted.

//Line 167 in cachesim.cpp
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;
    }
  }
}

Furthermore, the undo part needs to be taken into consideration as well. Under the circumstance of doing undo, if miss occurs and the policy is FIFO, we set the fifoflag again and we need to restore the oldway.

//Line 442 in cachesim.cpp
if (!trace.transaction.isHit && getReplacementPolicy() == ReplPolicy::FIFO) {
  m_fifoflag = true;
  way = oldWay;
}
//Line 82 in cachesim.cpp
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;
}

Demo video here,
https://github.com/mortbopet/Ripes/assets/67796326/b67aab30-17ee-4b3c-8fa7-ba56f905a282

Demo video demostrates the assembly code below,

lw a1 0(x0)
lw a1 512(x0)
lw a1 0(x0)
lw a1 512(x0)
lw a1 512(x0)
lw a1 1024(x0)
lw a1 1024(x0)
lw a1 1024(x0)
lw a1 1024(x0)
lw a1 0(x0)
lw a1 0(x0)
lw a1 0(x0)
lw a1 1536(x0)
lw a1 1536(x0)
lw a1 1536(x0)
addi a0 x0 1024
addi a0 a0 1024
lw a1 0(a0)

Full code is in the branch FIFO of my fork,
tinhanho@6772d1a

Let me know if there are any problems of my think and implement.

@mortbopet
Copy link
Owner

@tinhanho thank you for the further work - if you update the branch of this PR, it'll be a bit easier for me to review your code.

@tinhanho
Copy link
Author

tinhanho commented Jan 6, 2024

@mortbopet I have already updated the branch 😉

Comment on lines +108 to +139
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);
}
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.

Comment on lines +750 to +751
x = m_widthBeforefifo + m_fifoWidth / 2 -
m_fm.horizontalAdvance(fifoText) / 2;
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"))

Comment on lines +150 to +153
// ew.first = m_fifoIndexCounter;
// ew.second = &cacheLine[ew.first];
// m_fifoIndexCounter += 1;
// m_fifoIndexCounter %= getWays();
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

// m_fifoIndexCounter += 1;
// m_fifoIndexCounter %= getWays();
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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants