首页 > 解决方案 > 按位移位以查找内存地址的一部分

问题描述

这是一个测试程序,试图让我的位移操作工作。我希望将它添加到我的缓存模拟器程序中,但我什至无法让这部分工作。我的计划是使用位移 (<<) 和 (>>) 来隔离给定内存地址的部分(标记、集合、字等),但似乎在将位向右移动时,它填充了以前存在的值,而不是 0。这里首先是程序。

#include<iostream>
#include <cmath>

struct Address{
    unsigned int tag;
    unsigned int r;
    unsigned int word;
};

int main(){
    unsigned int tempAddress = 27; //0011011
    int ramSize = 128;
    int cacheSize = 64;
    int blockSize = 8;

    int cacheLines = cacheSize / blockSize;

    int addressLength = log(ramSize)/log(2);
    int wordBits = log(blockSize)/log(2);
    int rBits = log(cacheLines)/log(2);
    int tagBits = addressLength - (wordBits + rBits);

    struct Address address;

    address.tag = tempAddress >> (rBits + wordBits);
    address.r = tempAddress << (tagBits) >> (tagBits + wordBits);
    address.word = tempAddress << (rBits + tagBits) >> (rBits + tagBits);

    std::cout << "tag is: " << address.tag << "\n";
    std::cout << "r is: " << address.r << "\n";
    std::cout << "word is: " << address.word << "\n";


}

我发现当我的 tempAddress 为 [0-7] 时它工作正常,因为二进制 7 只影响前 3 位。同样,当为[8-63]时,tag和r是正确的,因为63影响前6位。在测试了许多地址后,我发现当左移后右移时,这些位被替换为它们之前的位置,而不是我认为应该的 0。

(r 是中间的部分。我称它为 r 是因为在直接映射中它被称为线,而在集合关联映射中它被称为集合)

编辑:

正如有人指出的那样,预期和产生的结果会有所帮助。我首先想保持缓存大小、内存大小和块大小不变,并且只更改地址。

因此,给定 tempAddress = 27(二进制的 0011011),word 应为 011(前 3 位),r 应为 011(后 3 位),set 应为 0(其余位)。输出是这样的:

tag is: 0
r is: 3
word is: 27

我发现如果标签和 r 之间的每个地址在 0 到 63(含)之间都是正确的,但 word 等于地址,这就是趋势。

现在,对于地址 = 65(1000001) 预期:

tag is: 1
r is: 0
word is: 1

输出:

tag is: 1
r is: 8
word is: 65

使用这些内存、缓存和块大小,要找到 r,我左移 1 次,右移 4 次。为了找到单词,我左移 4 次,然后右移 4 次。据我了解,当左移时,右边的位用 0 填充,当右移无符号整数时,左边的位用 0 填充。我的想法是,如果我左移直到只有这些位我需要,然后将它们右移回第一位,我将获得正确的值。然而,在许多地址中是一致的,在左移然后右移之后,有 1 的地方仍然存在。这就是为什么字总是等于地址的原因,因为我要左右移动 4 位。并且 r 始终等于右移 3 次的 7 位(因为我先向左 1,然后向右 4)。我是否误解了按位移位的工作原理?

标签: c++cachingsimulationmemory-address

解决方案


推荐阅读