【发布时间】:2010-04-28 01:17:53
【问题描述】:
背景:
我正在用 C 语言编写一个单级缓存模拟器来完成家庭作业,并且我得到了必须使用的代码。在我们对缓存的讨论中,我们被告知小缓存保存大地址的方法是将大地址拆分为缓存中的位置和一个标识标签。也就是说,如果你有一个 8 槽高速缓存但想存储地址大于 8 的东西,你取 3(因为 2^3=8)最右边的位并将数据放在那个位置;因此,如果您有地址 22,例如二进制 10110,您将采用最右边的 3 位 110,即十进制 5,并将其放入高速缓存的插槽 5。您还可以在此位置存储标签,即剩余的 10 位。
一个函数,cache_load,接受一个参数和整数指针。如此有效,我得到了这个 int* addr ,它是一个实际地址并指向某个值。为了将此值存储在缓存中,我需要拆分地址。但是,当我尝试直接使用指针时,编译器不喜欢。因此,例如,我尝试通过以下方式获得职位:npos=addr%num_slots
编译器生气并给我错误。我尝试强制转换为 int,但这实际上让我得到了指针指向的值,而不是数字地址本身。任何帮助表示赞赏,谢谢!
[编辑]
int load(int * addr) {
int value = (use_memory ? (*addr) : 0);
intptr_t taddr=(intptr_t) addr;
int npos=taddr % blocks;
int ntag=taddr / blocks;
printf("addr is %p, taddr is %p, npos is %d and ntag is %d\n",addr,taddr,npos,ntag);
当 addr 传入时,它的实际地址是 58,它指向的值是 88。我从那个 printf 得到的输出是:
addr 为 58,taddr 为 58,npos 为 0,ntag 为 11
所以看起来 taddr 得到了 58(使用 %p 打印时,使用 %d 打印时仍然显示 88),但是 npos 和 ntag 显示为 0 和 11(好像数学运算正在使用 88 运行)而不是我想要的 2 和 7。
代码是这样使用的:
void load_words (int n, int words[]) {
int i;
for (i=0; i<n; i++) {
load( (int *) (words[i] * 4));
cache_print();
}
}
【问题讨论】:
-
将指针转换为 int 不会给您它指向的值。但是,您通常应该改为使用
intptr_t。另外,请发布一些实际代码。 -
我现在放了一些代码,以及我得到的输出。我希望 taddr 与 addr (58) 相同,以便可以在其上使用模数和除法运算符。 edit 另外,如果我尝试这样转换,我会得到“`intptr_t' undeclared (first use in this function)”。
-
blocks 只是一个整数。我刚刚用新的输出更新了原始帖子中的代码。
-
@Airjoe 呵呵。初学者错误:
%p以十六进制(以 16 为底)而不是像%d那样以十进制(以 10 为底)打印。 -
那个 pastebin 链接是我教授给我的“好”代码,是的。我有一种强烈的感觉,我的教授可能跑题了,因为他通常是一名 Java 教授,而这个学期正在教授低级计算机组织课程。我真的不明白他为什么不使用 & 或者他为什么要乘以 4。现在,我将把它标记为已解决,直到我与他讨论。谢谢大家的帮助,时间很抱歉。
标签: c