缓存大小和计算缓存集

时间:2018-04-16 15:19:05

标签: c caching memory

我正在尝试了解缓存基础知识。 如果我有

#define OFFSET_BITS (6)                              // 64 bytes cache line
#define SET_INDEX_BITS (5)                           // 32 sets
#define TAG_BITS (64 - OFFSET_BITS - SET_INDEX_BITS) //
#define NWAYS (8)                                    // 8 ways cache.

这台机器的缓存大小是多少? 它只是添加偏移,设置和标记位? 另外,假设我有一个地址0x40000100,该地址的缓存是什么?我该如何计算?

1 个答案:

答案 0 :(得分:0)

假设您有一个数组,如下所示:

uint8_t myCache[1 << SET_INDEX_BITS][NWAYS][1 << OFFSET_BITS];

适用于NWAYS = 8SET_INDEX_BITS = 5OFFSET_BITS = 6;数组的大小(缓存的大小)将是16384字节(16 KiB)。

请注意&#34;缓存大小&#34;仅指缓存可以存储多少数据,并且不包括存储查找数据所需的标记的成本。

标签可以用第二个数组表示,如下所示:

myCacheTags[1 << SET_INDEX_BITS][NWAYS];

如果一个标签的成本为53位,则256个标签的成本为13568位;所以要实际实现缓存,你需要至少18080字节。当然在C中(你不能拥有53位整数数组),填充/对齐会花费更多(标签数组最终会导致每个标签64位)。

要在缓存中查找缓存行,您可以执行以下操作:

uint8_t *getCacheLine(uint32_t address) {
    int setIndex = (address >> OFFSET_BITS) & (( 1 << SET_INDEX_BITS) - 1);
    int myTag = address >> (OFFSET_BITS + SET_INDEX_BITS);

    for(int way = 0; way < NWAYS; way++) {
        if(myTag == myCacheTags[setIndex][way]) {
            return myCache[setIndex][way];
        }
    }
    return NULL;   // Cache miss
}

注意:通常标签包含某种&#34;有效或无效的&#34; flag(如果缓存中的条目根本不包含任何内容),通常标记还包含一些东西来表示最近使用的缓存行(对于某种&#34;最近最少使用的&#34;驱逐算法) 。我提供的示例代码是不完整的 - 它在执行if(myTag == myCacheTags[setIndex][way])时不会屏蔽这些额外的位,它不会检查任何有效/无效的标志,并且它没有&#39; t更新标记以指示最近使用了缓存行。