单选(1分)
假定主存地址位数为32位,按字节编址,主存和cache之间采用4-路组相联映射方式,主存块大小为4个字,每字32位,采用直写(Write Throght)方式和LRU替换策略,则能存放32K字数据的cache的总容量至少应有( )位。
得分/总分
A.
4672K
B.
1168K
C.
1184K
D.
4736K
正确答案:C你没选择任何选项
解析: C、cache共有32K字/4字=8K行,因为采用4-路组相联,因而共有8K/4=2K组,组号占11位;每个主存块为4字=4×32位=16B,故块内地址占4位。因此,标志占32-11-4=17位。4路组相联方式下,LRU替换算法需要每行有2位LRU位
(因为要表示0-3的数字吧)
;直写(Write Throght)方式无需修改位(dirty bit)。因而cache总容量为8K×(1+17+2+4×32)=1184K位。
8K 行 1 有效, 17标志,2位LRU位 ,
是不是因为每个主存块为4字=4×32位=16B 所以算式里面是4×32这个啊
也就是说 是不是 一个主存块有多少,这个数据就多少位啊
9单选(1分)
以下关于cache大小、主存块大小和cache缺失率之间关系的叙述中,错误的是( )。
得分/总分
A.
cache容量越大,cache缺失率越低
B.
主存块大小和cache容量无密切关系
C.
主存块大小通常为几十到上百个字节
D.
主存块越大,cache缺失率越低
正确答案:D你没选择任何选项
解析: D、主存块太小,则不能很好地利用空间局部性,从而导致缺失率变高,但是,主存块太大,也会使得cache行数变少,即cache中可以存放主存块的位置变少,从而降低命中率。因此,主存块不可以太小,也不可以太大,通常为几十到上百个字节。
10单选(1分)
某32位机按字节编址。数据cache有16行,主存块大小为64B,采用2-路组相联映射。对于以下程序A,假定编译时i, j, sum均分配在寄存器中,数组a按行优先方式存放,其首址为3200,则a[1][0]所映射的cache组号、程序A的数据cache命中率各是( )、( )。
short a[256][256];
……
short sum_array() {
int i, j;
short sum=0;
for (i=0; i < 256; i++)
for (j=0; j < 256; j++)
sum+=a[i][j];
return sum;
}
得分/总分
A.
2, 31/32
B.
4. 31/32
C.
2, 15/16
D.
4, 15/16
正确答案:A你没选择任何选项
解析: A、a[1][0]所映射的cache组号为[(3200+(1×256+0)×2)/64] mod (16/2) = 2。
首址为3200 每行有256个 1行 0列, short 2byte一个,主存块大小为64B ,数据cache有16行 ,2-路组相联映射
((开始地址 + (行号 * 一行元素个数 + 列号) * 数据种类的长度) / 主存块大小) % ( cache行个数 / 几路相联映射)
程序A的数据cache命中率分析如下:a[0][0]位于主存第3200/64=50块的起始处,
(首址为3200 ,主存块大小为64B )
按照数组访问顺序a[0][0]、a[0][1]、……、a[0][255]、a[1][0]、a[1][1]、……、a[1][255]、……,总是每64B/2B=32个数组元素组成一个主存块,
(,2-路组相联映射
) 被轮流装入数据cache的第2、3、……、7、0、1、…….、7、0、……. 组内的cache行中,因而这每一块的32个数组元素中,总是第一次不命中,以后每次都命中,因而命中率为31/32。
a[0][0]
、a[0][1]、…a[0][31] 所映射的cache组号为 2
a[0][32]
、a[0][33]、…a[0][63] 所映射的cache组号为 3
a[0][64]
、a[0][65]、…a[0][95] 所映射的cache组号为 4
a[0][96]
、a[0][97]、…a[0][127] 所映射的cache组号为 5
a[0][128]
、a[0][129]、…a[0][159] 所映射的cache组号为 6
a[0][160]
、a[0][161]、…a[0][191] 所映射的cache组号为 7
a[0][192]
、a[0][193]、…a[0][223] 所映射的cache组号为 8
a[0][224]
、a[0][225]、…a[0][255] 所映射的cache组号为 9
…
黄色的不命中
def arr_addr(begin_addr, row_num, col_num, one_row_elem_cnt, data_type_len):
addr = begin_addr + (row_num * one_row_elem_cnt + col_num) * data_type_len
print(f"arr[{row_num}][{col_num}] addr: {addr}")
return addr
def set_associative_arr(begin_addr, row_num, col_num, one_row_elem_cnt, data_type_len, main_memory_block_size,
cache_line_cnt, way_cnt):
"""
# a[1][0]所映射的cache组号为[(3200+(1×256+0)×2)/64] mod (16/2) = 2。
# 首址为3200 每行有256个 1行 0列, short 2byte一个,主存块大小为64B ,数据cache有16行 ,2-路组相联映射
组相联映射的关系到二维数组,我们要算a[1][0]所映射的cache组号
((开始地址 + (行号 * 一行元素个数 + 列号) * 数据种类的长度) / 主存块大小) % ( cache行个数 / 几路相联映射)
:param begin_addr: 首址为3200
:param row_num: 1行
:param col_num: 0列
:param one_row_elem_cnt: 每行有256个
:param data_type_len: short 2byte一个
:param main_memory_block_size: 主存块大小为64B
:param cache_line_cnt: 数据cache有16行
:param way_cnt: ,2-路组相联映射
:return:
"""
group_num = (arr_addr(begin_addr, row_num, col_num, one_row_elem_cnt, data_type_len) / main_memory_block_size) % (
cache_line_cnt / way_cnt)
# group_num = ((begin_addr + (row_num * one_row_elem_cnt + col_num) * data_type_len) / main_memory_block_size) % (
# cache_line_cnt / way_cnt)
group_num = int(group_num)
print(f"arr[{row_num}][{col_num}]所映射的cache组号为 {group_num}")
def arr_group_list():
# ==a[0][0]==、a[0][1]、....a[0][31] 所映射的cache组号为 2
col_num = 0
group_num = 2
for i in range(9):
print(f"==a[0][{col_num}]==、a[0][{col_num + 1}]、....a[0][{col_num + 31}] 所映射的cache组号为 {group_num}")
col_num += 32
group_num += 1
set_associative_arr(3200, 0, 31, 256, 2, 64, 16, 2)
set_associative_arr(3200, 0, 32, 256, 2, 64, 16, 2)
arr_group_list()
2.0