我正在敲打头来解决这个问题,甚至无法前进一步,问题就像:
考虑以下C程序:
int X[N];
int i;
int step = M; // M is some predefined constant
for (i = 0; i < N; i += step) X[i] = X[i] + 1;
如果此程序在具有4 KB页面大小和64项TLB的计算机上运行,那么M和N的哪些值将导致每次执行内循环时TLB未命中?
任何人都可以给我一些提示,我该如何解决?
答案 0 :(得分:7)
很简单。首先,您必须了解TLB究竟做了什么?
提示是它是一个缓存,有助于将virtual address
转换为physical address
。所以你知道页面大小是4千字节。所以如果有一个数组可以说无限长。您正在for循环中从0到无穷大访问它。第一次访问数组X [0]将导致TLB未命中并加载第一个TLB。然后对于接下来的4095次访问,它不会被遗漏,因为它存在于TLB中(请记住这是因为页面大小为4096 = 4KB)。那么接下来的地址是X [4096],这将导致TLB未命中。因此,您会看到,对于每4096个地址增量,您将有一个TLB未命中。所以我们确定M = 4096/sizeof(int)
。
现在你也知道你有64项TLB缓存。因此,在加载了64个TLB条目后,您将拥有一个完整的TLB。要加载第65个条目,您必须删除第一个条目。 (请注意,可以有不同的替换机制。我们假设它是一个简单的机制)。因此,在第65个条目加载后,访问X [0]时的第一个条目已被删除。因此,如果您尝试现在访问X [0],将会有TLB未命中替换X [4096]所需的条目,依此类推。所以你需要64 * 4096 = 256 KBytes
的大小来充分利用TLB缓存。但是,您希望每个步骤都有TLB缓存未命中。因此对于64条入口TLB缓存,您需要的数组大小相当于65个条目。因此N = 65 * 4096 / sizeof(int)
。
希望这能给出一些提示!
答案 1 :(得分:2)
当页面的虚拟地址不在TLB中时,会发生TLB未命中。
鉴于TLB为64个条目,如果您使用虚拟地址0 * 4096,1 * 4096,2 * 4096,...,63 * 4096完全预先填充它(您可以通过访问相关页面中的内存来填充它) )然后请求从64 * 4096到64 * 4096 + 4095的虚拟地址访问,该访问将导致TLB未命中(因为64 * 4096尚未在TLB中)。
然后,如果现在存储地址64 * 4096的条目(在TLB未命中之后,驱逐64个条目之一并用虚拟地址64 * 4096替换它并与其对应的物理地址)之前有虚拟地址0 * 4096,然后从虚拟地址0到4095访问内存将导致另一个TLB未命中(因为虚拟地址0 * 4096的条目已从TLB逐出,并替换为VA 64 *的条目4096)。
根据TLB的这种行为,你应该提出满足要求的M
和N
。