以下代码将在具有以下缓存结构的CPU上运行:
我正在准备期中考试,有一个问题。修改此代码,以尽量减少惩罚的数量。根据L1、L2和L3缓存计算缓存命中次数和缓存丢失数。
我试着通过环路交汇处来解决这个问题。如果我更改为下面这样的代码,那么就会有一个连续的访问,而不是每隔16,364个单词跨出一次内存。
unsigned int A[65536];
int i,j;
for (j=1 ; j<128; j++)
for (i=0 ; i<65536-256 ; i++)
A[i]=A[i]+A[i+j];
但我还是坚持了缓存的命中和失误。有人能跟我解释一下吗?
发布于 2017-04-28 11:02:23
假设unsigned int
为4个字节,则数组的大小为4* 65536 =256 is。您的L3缓存只能容纳多达64 L3。
为了最小化惩罚,您应该做的第一件事是将循环分成4个子组,这样一旦您将一个条目加载到L3,您就应该在被逐出之前完全使用它。
unsigned int A[65536];
int i,j,k;
for (k=0 ; k<65536-256; k+=16384)
for (j=1 ; j<128; j++)
for (i=k ; i<MIN(k+16384,65536-256) ; i++) //define a MIN function to return minimum
A[i]=A[i]+A[i+j];
现在,要计算缓存命中和丢失,一个缓存线可以容纳该数组的4个条目。当您第一次访问A时,这将是L1、L2和L3中的一次失败。当从内存中提取时,您不只是获取A,还将获取A1、A2和A3,因为一个背景色可以容纳它们的全部4个。
在同一条指令中,您还可以访问Ai+j,在本例中将是A1,这将是成功的。所以就像,
First iteration
A[i] - A[0] - Miss
A[i+j] - A[1] - Hit
Second Iteration
A[i] - A[1] - Hit
A[i+j] - A[2] - Hit
Third Iteration
A[i] - A[2] - Hit
A[i+j] - A[3] - Hit
Forth Iteration
A[i] - A[3] - Hit
A[i+j] - A[4] - Miss // This will cause to fetch A[4], A[5], A[6], A[7]
A模式一直持续到L1被填充为止。
https://stackoverflow.com/questions/43676711
复制相似问题