Cache Lab:Part B(52.6/53分)【矩阵转置的分块算法】

目录

任务描述

32 × 32

baseline

try1:给对角线上的块再次细分块

try2:对角块依次错位

成功:对角块两两交换 

成功:其他方法

64 × 64 

baseline

对角线优化+普通块转置顺序调整(7.6/8分)

61 × 67

成功:bsize=16*16

测试


任务描述

要求在trans.c中编写一个转置函数,从而导致尽可能少的miss。缓存的参数是 (s = 5, E = 1, b = 5)。三种测试用例的矩阵大小分别为:
        • 32 × 32 (M = 32, N = 32)
        • 64 × 64 (M = 64, N = 64)
        • 61 × 67 (M = 61, N = 67)

规定:仅使用12个局部变量,不能使用递归,不能修改A数组(可任意修改B数组),不允许使用malloc。

提示:你的代码只需要针对这三种情况是正确的,并且你可以针对这三种情况进行专门优化。特别是,你的函数完全可以显式检查输入大小并实现针对每种情况优化的单独代码。

32 × 32

baseline

下图是32*32数组的分块情况,每一个小格代表一个block(由前提条件b=5,得出一个块是32字节,由于是int数组,所以一个block能存8个元素)

上面是16个大块。

转置时依次扫描大块1~16,将块内元素转置后放在数组B对应的位置。可以发现,除了对角块,其余都是没有冲突未命中的。

int i, j, k, q, tmp;
if (M == 32 && N == 32)
{for (k = 0; k < 4; k++){for (q = 0; q < 4; q++){for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = A[k * 8 + i][q * 8 + j];B[q * 8 + j][k * 8 + i] = tmp;}}}}
}

 由于PartA我们已经实现了模拟器了,所以miss的值肯定是能手算出来的。我们先大概算一下。

对于图上未着色的12个大块,12*16=192;对于对角线上的4个大块(着色的),4*(10+4+4+4+4+4+4+3)=144;故大约是192+144=336。

测试程序算的是344,大差不差。但仍需优化。 修改思路就是对于对角线进行进一步优化。

try1:给对角线上的块再次细分块

本来一个大块是8*8的,对于对角线,再一分为四,变为4*4。

还是先来预算一下结果:12个大块跟baseline一样是192;对角线上8个4*4块:8*(6+4+4+3)=138;其余8个4*4块:8*8=64;总计192+138+64=392。

测试程序计的数也是392,这种方法更差了。

int i, j, k, q, i2, j2, k2, q2, tmp;
if (M == 32 && N == 32)
{for (k = 0; k < 4; k++){for (q = 0; q < 4; q++){if (k == q){for (k2 = 0; k2 < 2; k2++){for (q2 = 0; q2 < 2; q2++){for (i2 = 0; i2 < 4; i2++){for (j2 = 0; j2 < 4; j2++){tmp = A[k * 8 + k2 * 4 + i2][q * 8 + q2 * 4 + j2];B[q * 8 + q2 * 4 + j2][k * 8 + k2 * 4 + i2] = tmp;}}}}}else{for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = A[k * 8 + i][q * 8 + j];B[q * 8 + j][k * 8 + i] = tmp;}}}}}
}

try2:对角块依次错位

具体来说,转置完的1号大块存在6号大块,6号存在11号,11号存在16号。16号进行普通转置。

int i, j, k, q, tmp;
if (M == 32 && N == 32)
{for (k = 0; k < 4; k++){for (q = 0; q < 4; q++){if (k == q && k != 3){for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = A[k * 8 + i][q * 8 + j];B[q * 8 + 8 + j][k * 8 + 8 + i] = tmp;}}for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = B[k * 8 + i + 8][q * 8 + j + 8];B[k * 8 + i][q * 8 + j] = tmp;}}}else{for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = A[k * 8 + i][q * 8 + j];B[q * 8 + j][k * 8 + i] = tmp;}}}}}
}

现象:变好,m=305(只差一点点) 

成功:对角块两两交换 

具体来说,A的1号转置完成后存到B的6号,A的6号转置完存到B的1号去。然后,B的1号和6号交换。11号和16号同理。

现象:m=276,成功。

int i, j, k, q, tmp;
if (M == 32 && N == 32)
{for (k = 0; k < 4; k++){for (q = 0; q < 4; q++){if (k == q && k % 2 == 0){for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = A[k * 8 + i][q * 8 + j];B[q * 8 + 8 + j][k * 8 + 8 + i] = tmp;}}}else if (k == q && k % 2 == 1){for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = A[k * 8 + i][q * 8 + j];B[q * 8 - 8 + j][k * 8 - 8 + i] = tmp;}}for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = B[k * 8 + i][q * 8 + j];B[k * 8 + i][q * 8 + j] = B[k * 8 - 8 + i][q * 8 - 8 + j];B[k * 8 - 8 + i][q * 8 - 8 + j] = tmp;}}}else{for (i = 0; i < 8; i++){for (j = 0; j < 8; j++){tmp = A[k * 8 + i][q * 8 + j];B[q * 8 + j][k * 8 + i] = tmp;}}}}}
}

成功:其他方法

以上思路是我独立想出的。看了其他人的解法,在此补充一下:

对角线处发生的较多conflict miss的原因是,A和B相同大块之间是占有相同索引位置的cache的。如果先把A的对角线上的大块原封不动的挪到对应位置的B大块,然后让B大块原地转置,原地转置是不存在conflict miss的。

问题就变成了怎么实现“把A的对角线上的大块原封不动的挪到对应位置的B大块”,因为同时访问AB的对应位置就会发生conflict miss。

其实示例程序的tmp变量是个提示。可以多来几个局部变量,当做一个临时数组。也就是将循环最内层完全展开。

这种方法的代码请见 https://zhuanlan.zhihu.com/p/410662053

64 × 64 

baseline

现象:m=1892(满分1300)

对角线优化+普通块转置顺序调整(7.6/8分)

对角线转置方法:

普通块:

	if (M == 64 && N == 64){//k q 将64*64棋盘分为64个8*8的小格for (k = 0; k < 8; k++){for (q = 0; q < 8; q++){//处理对角线if (k == q){int bias = 8;if (k % 2 == 1) bias = -8;for (i = 0; i < 4; i++)for (j = 0; j < 4; j++)B[k * 8 + bias + j][q * 8 + bias + i] = A[k * 8 + i][q * 8 + j];for (i = 0; i < 4; i++)for (j = 4; j < 8; j++)B[k * 8 + bias + j][q * 8 + bias + i] = A[k * 8 + i][q * 8 + j];for (i = 4; i < 8; i++)for (j = 4; j < 8; j++)B[q * 8 + bias + j][q * 8 + bias + i] = A[k * 8 + i][q * 8 + j];for (i = 4; i < 8; i++)for (j = 0; j < 4; j++)B[k * 8 + bias + j][q * 8 + bias + i] = A[k * 8 + i][q * 8 + j];}else{// 对于不在对角线上的12个8*8的普通格,每个格还是一分为四,每小格为4*4,按照1,2,4,3的顺序从A转置存到Bfor (i = 0; i < 4; i++)for (j = 0; j < 4; j++)B[q * 8 + j][k * 8 + i] = A[k * 8 + i][q * 8 + j];for (i = 0; i < 4; i++)for (j = 4; j < 8; j++)B[q * 8 + j][k * 8 + i] = A[k * 8 + i][q * 8 + j];for (i = 4; i < 8; i++)for (j = 4; j < 8; j++)B[q * 8 + j][k * 8 + i] = A[k * 8 + i][q * 8 + j];for (i = 4; i < 8; i++)for (j = 0; j < 4; j++)B[q * 8 + j][k * 8 + i] = A[k * 8 + i][q * 8 + j];}// 交换if (k == q && k % 2 == 1){for (i = 0; i < 4; i++)for (j = 0; j < 4; j++)swap(&B[k * 8 + i][q * 8 + j], &B[k * 8 - 8 + i][q * 8 - 8 + j]);for (i = 0; i < 4; i++)for (j = 4; j < 8; j++)swap(&B[k * 8 + i][q * 8 + j], &B[k * 8 - 8 + i][q * 8 - 8 + j]);for (i = 4; i < 8; i++)for (j = 0; j < 4; j++)swap(&B[k * 8 + i][q * 8 + j], &B[k * 8 - 8 + i][q * 8 - 8 + j]);for (i = 4; i < 8; i++)for (j = 4; j < 8; j++)swap(&B[k * 8 + i][q * 8 + j], &B[k * 8 - 8 + i][q * 8 - 8 + j]);}}}}

61 × 67

要求m<2000,比较宽松。

成功:bsize=16*16

    if (M == 61 && N == 67){int bsize_x = 16;int bsize_y = 16;for (k = 0; k <= 67/bsize_x; k++)for (q = 0; q <= 61/bsize_y; q++)for (i = 0; i < bsize_x && k*bsize_x+i<67; i++)for (j = 0; j < bsize_y && q*bsize_y+j < 61; j++)B[q * bsize_y  + j][k * bsize_x  + i] = A[k * bsize_x  + i][q * bsize_y  + j];}

测试

注意测试程序driver.py要用python2运行,python3是报错的 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3+vite搭建基础架构(3)--- 使用dayjs

Vue3vite搭建基础架构&#xff08;3&#xff09;--- 使用dayjs 说明官方文档vite.config.js别名配置安装dayjs安装命令 使用dayjs将dayjs封装为自己的日期工具类使用dataUtil.js日期工具类示例 说明 这里记录下自己在Vue3vite的项目使用dayjs的过程&#xff0c;不使用ts语法&a…

最新XC主题 支持六种主题样式 去除域名授权全解密源码 一款多样式主题

Typecho 最新XC主题 去除域名授权全解密源码 这是一款多样式主题&#xff0c;首页支持六种主题样式&#xff0c;支持Pjax优化访问速度&#xff0c;多种单页&#xff0c;如友链、说说等。评论支持表情&#xff0c;自定义编辑器&#xff0c;支持其他样式功能。该主题功能性挺高&…

音视频数字化(音频数字化)

在音视频领域,人们始终追求无限还原现场效果,因此音频越逼真越好,视频越清晰越好。之所以我们需要将音视频信号由模拟转为数字,目的是在录制、存储、编辑、复制、回放等环节的不失真,尽量保持原有细节,不因以上操作,导致音画的质量下降。 为此,视频系统分辨率越来越高,…

【Java程序设计】【C00207】基于(JavaWeb+SSM)的宠物领养管理系统(论文+PPT)

基于&#xff08;JavaWebSSM&#xff09;的宠物领养管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的宠物领养系统 本系统分为前台系统、管理员、收养者和寄养者4个功能模块。 前台系统&#xff1a;游客打开系统…

k8s-HPA

前提条件 安装有**Metrics Server**,HPA的运行监控指标需要由Metrics Server 提供 文档&#xff1a;https://github.com/kubernetes-sigs/metrics-server?tabreadme-ov-file#readme 快速自动缩放&#xff0c;每15秒收集一次指标(可配置)。 资源效率&#xff0c;为集群中的每…

网络防御安全:2-6天笔记

第二章&#xff1a;防火墙 一、什么是防火墙 防火墙的主要职责在于&#xff1a;控制和防护。 防火墙可以根据安全策略来抓取流量之后做出对应的动作。 二、防火墙的发展 区域&#xff1a; Trust 区域&#xff0c;该区域内网络的受信任程度高&#xff0c;通常用来定义内部…

VSCode 设置代理

Open Visual Studio Code, click the settings icon in the lower left corner, and click Settings.

yii2 mongodb 操作

->where([<>,review,""]) 不等于空 $where [newstypeid>[$in>$categoryIdArr]]; 类似mysql in操作 &#xff08;$categoryIdArr是数组&#xff09; ->where([label>[$regex >赞美诗]]) 模糊搜索操作 $where [status>1,name>[$rege…

C++语法 内存区域 和 引用

代码区 存放函数体的二进制代码 由操作系统进行管理 全局区 存放全局变量和静态变量以及常量 存放全局变量 静态变量 常量&#xff08;字符串常量 全局const常量&#xff09; 栈区 由编译器自动分配释放&#xff0c;存放函数的参数值&#xff0c;局部变量等。不要返回局部…

【论文笔记】Multi-Chain Reasoning:对多思维链进行元推理

目录 写在前面1. 摘要2. 相关知识3. MCR方法3.1 生成推理链3.2 基于推理链的推理 4. 实验4.1 实验设置4.2 实验结果 5. 提及文献 写在前面 文章标题&#xff1a;Answering Questions by Meta-Reasoning over Multiple Chains of Thought论文链接&#xff1a;【1】代码链接&…

【数据分享】1929-2023年全球站点的逐日最高气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2023年全球气象站…

Git 怎么设置用户的权限

在团队协作的软件开发中&#xff0c;对于版本控制系统Git来说&#xff0c;确保代码与数据的安全性至关重要。为了实现这一目标&#xff0c;Git提供了灵活且可定制的用户权限管理机制。下面将简单的探讨一下Git如何设置用户的权限&#xff0c;以及如何保护代码和数据。 用户身份…

Nginx 多项目部署,vue刷新404 解决方案

网上找的资料大多都解决不了&#xff0c;废话不多说直接告诉你解决方法。 环境是 TP6 VUE前端官网 VUE 后台管理 部署 两个项目 刷新 404 解决方案 Nginx 配置 直接贴图 如果解决了&#xff0c;给我顶起来&#xff0c;让更多人 快速的解决。

南京观海微电子---如何减少时序报告中的逻辑延迟

1. 引言 在FPGA逻辑电路设计中&#xff0c;FPGA设计能达到的最高性能往往由以下因素决定&#xff1a; ▪ 工作时钟偏移和时钟不确定性&#xff1b; ▪ 逻辑延迟&#xff1a;在一个时钟周期内信号经过的逻辑量&#xff1b; ▪ 网络或路径延迟&#xff1a;Vivado布局布线后引…

element-ui button 组件源码分享

element-ui button 源码分享&#xff0c;基于对源码的理解&#xff0c;编写一个简单的 demo&#xff0c;主要分三个模块来分享&#xff1a; 一、button 组件的方法。 1.1 在方法这块&#xff0c;button 组件内部通过暴露 click 方法实现&#xff0c;具体如下&#xff1a; 二、…

如何使用 Supabase Auth 在您的应用程序中设置身份验证

在本文中&#xff0c;您将学习基本的关键概念&#xff0c;这些概念将帮助您掌握身份验证和授权的工作原理。 您将首先了解什么是身份验证和授权&#xff0c;然后了解如何使用 Supabase auth 在应用程序中实现身份验证。 &#xff08;本文内容参考&#xff1a;java567.com&…

Open CASCADE学习|球面上曲线长度计算

球和球面是数学和物理学中非常重要的概念&#xff0c;它们在许多领域都有广泛的应用。 球面是指所有与固定点等距离的点的集合&#xff0c;这个固定点被称为球心&#xff0c;而这个等距离的长度就是球的半径。球面是一个二维曲面&#xff0c;它是三维空间中点与距离之间关系的…

Docker容器引擎(5)

目录 一.docker-compose docker-compose的三大概念&#xff1a; yaml文件格式&#xff1a; json文件格式&#xff1a; docker-compose 配置模板文件常用的字段&#xff1a; 二.Docker Compose 环境安装&#xff1a; 查看版本&#xff1a; 准备好nginx 的dockerfile的文…

AS-V1000产品介绍:支持GA/T1400视图库标准(可通过GA/T1400接入海康、华为、大华等图传前端设备,实现图传功能)

目 录 一、概述 二、AS-V1000视频监控管理平台的特点 二、视频监控平台通过GA/T1400接入前端设备 &#xff08;一&#xff09;接入华为GA/T1400前端设备 &#xff08;二&#xff09;接入大华GA/T1400前端设备 &#xff08;三&#xff09;接入海康威视GA/…

杂题——试题-算法训练-P0602

分析&#xff1a; 把要重排序的数字转成数组对数组进行排序&#xff0c;从小到大排序数组转成字符串&#xff0c;字符串转成数字&#xff0c;得到最小数再把最小数的字符串反转&#xff0c;得到最大数注意&#xff1a; 在java语言中&#xff0c;如果使用Arrays.toString(digits…