在缓存c++中查找命中/未命中

Find hit/miss in cache c++

本文关键字:查找 c++ 缓存      更新时间:2023-10-16

我的硬件很吃力。它要求读取一个跟踪文件,其中每一行都有引用类型和十六进制地址。例如,文件中的第一行的地址为0x4ef1200231,带有指令类型。它还要求检查缓存中的此地址是否命中或未命中(在L1和L2中)。我不太确定如何编写c++(我是新手)来检查它是否命中。

我想象有一个函数,比如地址(long int),如果我调用地址(0x4ef1200231),控制台可以告诉我这个地址在L1是命中还是未命中,如果是未命中,那么调用另一个函数在L2检查这个地址。这太天真了吗?请帮忙。谢谢

---轨迹中的几行---
4ef1200231国际
2ff1e0122234 WR
82039 ef9a3 R

注释:Int表示指令,WR表示数据写入,R表示数据读取。问题是在阅读了整个跟踪文件之后,总共有多少次命中和未命中。谢谢

对于C++初学者来说,这个问题可能太高级了,但这里有一些关于如何实现解决方案的解释。。。。

首先,您需要有一个模仿各级缓存使用的逻辑的容器:最简单(而且可能足够)的容器是最近使用最少(LRU)的数据结构。这样做的目的是记录一个固定的最大数量的缓存中元素,当访问一个元素时,它会在列表中搜索它:如果找到它,它会被移动到列表的顶部/前面,替换第一个和随后的列表元素,直到它留下的空白再次被填满。如果它不在列表中,那么它也会被添加到顶部,所有其他元素都会下移以腾出空间,如果列表达到最大大小,则最后一个元素会被删除。为了很好地实现LRU,您需要能够按值快速查找元素,同时在列表中间快速插入和删除元素。这最好使用unordered_maplist的组合来完成,但单独实现它比作为C++初学者所能合理预期的要多。你可以从只使用列表开始——搜索会很慢(O(n)或线性/暴力),但你可以让它正常工作。

给定这样一个LRU类,您可以设置两个实例的大小来表示L1和L2缓存中的页面,然后对于输入文件中的每个地址,您在L1中查找该页面(例如,对于4k页面,您可以将其除以4096,或者逐位并取4095的逐位否定,或者逐比特或取4095,或者将其右移12次等),必要时返回L2。"它已经在缓存中了吗"代码可以保留命中/未命中计数器。

下面是一些让你开始的示例代码:

template <typename T>
class Dumb_LRU
{
    Dumb_LRU(size_t max_size) : n_(max_size) { }
    bool operator()(const T& t)
    {
        std::list<T>::iterator i = std::find(l_.begin(), l_.end(), t);
        if (i == l_.end())
        {
            l_.push_front(t);
            if (l_.size() > n_)
                l_.pop_back();
            return false;
        }
        if (i != l_.begin()) // not already the first element...
        {
            l_.erase(i);
            l_.push_front(t);
        }
        return true;
    }
  private:
    std::list<T> l_;
    size_t n_;
};

然后你可以这样做你的模拟:

static const size_t l1_cache_pages = 256;
static const size_t l2_cache_pages = 2048;
static const size_t page_size = 4096;
Dumb_LRU<size_t> l1(l1_cache_pages);
Dumb_LRU<size_t> l2(l2_cache_pages);
size_t address;
std::string doing_what;
int l1_hits = 0, l1_misses = 0, l2_hits = 0, l2_misses = 0;
while (std::cin >> address >> doing_what)
{
    if (l1(address / page_size))
        ++l1_hits;
    else
    {
        ++l1_misses;
        if (l2(address / page_size))
            ++l2_hits;
        else
            ++l2_misses;
}
// ...print out hits/misses...