缓存块标签大小

时间:2018-12-04 20:19:35

标签: c caching bit-manipulation

我正在使用gcc作为编译器在linux上用C编写一个缓存模拟程序,并且大部分工作已经完成。只有少数测试用例出错(应击中的数千个联邦地址中有几项缺失)。我在命令行上指定缓存属性。我怀疑代码中的错误与标签有关(如果事情没有实现,那么它们的标签就不应该匹配)。所以我的问题是:我计算标签正确吗?

//setting sizes of bits
int offsetSize = log2(lineSize);
int indexSize = 0;
if (strcmp(associativity,"direct") == 0){//direct associativity
  indexSize = log2(numLines);
}else if (assocNum == numLines){//fully associative
  indexSize = 0;
}else{//set associative
  indexSize = log2(assocNum);
}

address = (int) strtol(readAddress,&eptr,16);
unsigned long long int mask = 0;

//get the offset Bits
mask = (1 << offsetSize) - 1;
offsetBits = address & mask;

//get the index bits
mask = (1 << (indexSize)) - 1;
mask = mask << offsetSize;
indexBits = (address & mask) >> offsetSize;

//get tag bits
tagBits = address >> (offsetSize+indexSize);

要馈送的地址通常为48位,因此变量address和mask的类型为unsigned long long int。我认为我遇到的问题是,当我应该只从大地址中取出一小部分位时,我正在占用地址的所有高位字节。

例如:我在4路组关联缓存中有32个缓存行,块大小为4。

offsetSize = log2(4)= 2

indexSize = log2(4)= 2

无论地址大小如何,我的代码当前都占用地址的高位,减去最后4位。我应该只使用高28位吗? (tagSize =(8 * 4)-3-2)

1 个答案:

答案 0 :(得分:1)

  

无论地址大小如何,我的代码当前都占用地址的高位,减去最后4位。我应该只使用高28位吗?

标签必须包含所有高位,以便可以使用标签来确定它是否是缓存命中。

如果地址是48位并且分为3个字段,则您将有一个2位的“高速缓存行中的偏移量”字段,一个2位的“高速缓存中的索引”字段和一个44位的“高位”字段必须存储在“代码”字段中。如果您仅在标记中存储28位,那么当您应该遇到高速缓存未命中时,您会遇到高速缓存命中(因为高速缓存中的条目恰好包含28位恰好匹配的其他地址的数据)。

请注意,您可以/应该将“关联性”理解为并行运行的高速缓存行的数量(其中直接映射的只是“ associativity = 1”,而完全关联的只是“ associativity = total_cache_size” / cache_line_size”)。关联性对索引大小没有直接影响(仅高速缓存行集的大小与索引大小有关),并且您遇到的问题可能与indexSize = log2(assocNum);有关(这没有意义)

换句话说:

    if( direct_mapped ) {
        associativity = 1;
    } else {
        max_associativity = total_cache_size / cache_line_size;
        if( fully_associative || (associativity > max_associativity) ) {
            associativity = max_associativity;
        }
    }

    set_size = total_cache_size / associativity;
    number_of_lines_in_set = set_size / cache_line_size;

    offset_size = log2(cache_line_size);
    index_size = log2(number_of_lines_in_set);
    tag_size = address_size - index_size - offsetSize;