一、实验截图

01

02

03

04

二、transpose_submit函数的实现原理

由writeup文件里的要求可知,partB的cache的参数为s=5, E=1, b=5,

可得出共有32列,每列可以存储8个int值,也就是说最多可同时存328个数据,第一问中是要转置3232矩阵,假设原矩阵为A,变换后矩阵为B,

暴力解法:

在将A导入缓存中由于在二维数组里相同行的数据在内存上也是连续的所以可以同时写入后面8个元素。

可以理解为每隔8个元素就会发生一次miss,这是不可避的。

在写入B的时候由于是按列写的,并不在空间上连续,所以每次写的时候都会出现miss,在写入一个数字后,同样也会将它同行后的7个元素也加入到缓存中,但是在第一列写完后缓存肯定已经饱和,加入缓存中的后7个元素早已被替换了,所以在写入第二列的时候也会发生和写入第一列时一样的情况。

分析:

只要矩阵的大小小于缓存的总大小,那么在理想的情况下,在最初的强制不命中(即缓存为空导致的不命中)后,整个矩阵都会被加载进入缓存。在这之后的所有对于B矩阵的不连续写的引用都会命中。

如果能有效利用在写入B时已经加入缓存的未利用的部分,将会有效优化在写入B时出现的大面积miss,根据矩阵分块算法,由于一次性加载8个元素进入缓存,尝试8*8分块,得到结果

05

Miss数343,并不是满分,原来是对角线上的块,因为在缓存中的位置也相同,可能会发生相互冲突,从而引起不必要的miss。解决办法是将对角线中间的取出来存入对应的变量在传给b,这样就能保证不会出现B将A的缓存驱逐后再存入A引起miss的情况。

同样的,对于6464也能很轻易想到88分块,但是由于列数增多,64*8已经大于cache的范围了,所以很容易出现miss,经过测试得到结果miss数达4611次

06

显然这种方法是有错误的,考虑4*4分块结果,明显这种方法没能充分运用cache,因为cache一组能存八个数据。

根据查阅资料获得思路,将矩阵进行八分块再四分块然后进行读写,完成。

61*67分块经过测试,无法使用比较完美的拟合8分块,故使用试用16分块满足要求