我为2路组关联缓存模拟器编写了代码。模拟器从文本文件中获取输入,如下所示:
输入文件:
read 0x04000000
write 0x02000000
read 0x04000008
从这里有一个方法可以为它提供缓存大小和块大小。当前实现的方式是使用直写缓存策略。我想用回写策略代替它。
以下是我的头文件的相关部分:
class Cache
{
private:
QStringList m_Instructions;
QList<QString> m_Output;
public:
Cache(QString);
~Cache();
void TwoWaySA(int, int);
void print(QString);
};
以下是该方法的代码:
void Cache::TwoWaySA(int cacheSize, int blockSize)
{
// Determine Properties
int blockCount = cacheSize/blockSize;
int numWays = 2;
int numSets = blockCount/numWays;
int cacheMemory[numSets][numWays+1];
// Reset Cache_Memory for New Cache Specs
for(int i = 0; i < numSets; i++)
{
cacheMemory[i][0] = i;
for(int j = 0; j <= numWays; j++)
{
cacheMemory[i][1] = 0;
cacheMemory[i][2] = 0;
}
}
float hit = 0;
int bytesMtoC = 0;
int bytesCtoM = 0;
for(int i = 0; i < m_Instructions.length(); i++)
{
QString instruction = m_Instructions[i];
QString memAddress_Text = instruction.split(" ")[1];
bool ok;
int memAddress_Num = memAddress_Text.toInt(&ok, 16);
int set = (memAddress_Num/blockSize)%numSets;
int tag = memAddress_Num/blockSize/numSets;
if(m_Instructions[i].contains("read"))
{
int flag = 0;
for(int i = 1; i <= numWays; i++)
{
if(cacheMemory[set][i] == tag)
{
hit++;
flag = 1;
}
}
if(flag != 1)
{
// LRU?
bytesMtoC += blockSize;
cacheMemory[set][1] = tag;
}
}
if(m_Instructions[i].contains("write"))
{
int flag = 0;
for(int i = 1; i <= numWays; i++)
{
if(cacheMemory[set][i] == tag)
{
hit++;
flag = 1;
bytesCtoM += blockSize;
}
}
if(flag != 1)
{
// LRU?
cacheMemory[set][2] = tag;
bytesMtoC += blockSize;
bytesCtoM += blockSize;
}
}
}
float hitRatio = hit/m_Instructions.length();
QString output;
QString cache_size = QString::number(cacheSize);
QString block_size = QString::number(blockSize);
QString cache_type = "2W";
QString hit_ratio = QString::number(hitRatio, 'g', 2);
QString memTOcache = QString::number(bytesMtoC);
QString cacheTOmem = QString::number(bytesCtoM);
QString comparisons = "2";
output.append(cache_size).append(" ").append(block_size).append(" ")
.append(cache_type).append(" ").append(hit_ratio).append(" ")
.append(memTOcache).append(" ").append(cacheTOmem).append(" ")
.append(comparisons);
m_Output.append(output);
}
我知道回写政策和直写政策之间的区别。写回内容然后写入缓存然后写入内存。通过内容写入同时写入缓存和内存。
但是,我不知道如何实现这一点。谢谢你们的帮助,我真的很感激。
答案 0 :(得分:0)
您需要跟踪缓存中每行的三种状态:
就常见的MESI protocol而言,这些对应于“I - 无效”,“E - 独有”和“M - 修改”状态。在这个模拟中没有共享状态,因为你只考虑一个处理器,所以这真的是一个“MEI”协议。
分配一行时,您需要选择在缓存中分配的位置。如果要替换的行处于M状态(已修改/有效,脏),则需要为该行发送受害者写回,以便您可以安全地分配新行。如果它处于E状态,你可以在不派遣受害者的情况下丢弃该线路。
如果为响应CPU读取而分配新行,则新行将进入E状态(Exclusive / Valid,clean)。如果为响应CPU写入而分配一行,则新行将进入M状态(已修改/有效,脏)。
因此,在您的代码中,您需要跟踪每一行的M / E / I状态,并处理在重新分配一行以响应错过缓存的CPU请求时发生的转换。此外,根据您的替换策略(LRU,随机,FIFO),您可能需要跟踪每个集合的一些额外状态,假设有一个组关联结构。
你有相当多的代码 - 真的有点太多了。但是,考虑到缓存协议以及您需要跟踪的状态,您应该能够使用铅笔和纸张计算来自CPU的读取和写入序列在缓存行方面应该变成什么分配和受害者回写。一旦你手工完成它,你可能会更清楚如何在软件中实现状态转换。
如果您在制作翻译时遇到困难,那么您应该能够在此处提供更简洁的问题。
祝你好运。