哈工大csapp-LAB3程序优化
实验报告
实 验(三)
题 目 优化
专 业 人工智能(未来技术)
学 号 7203610716
班 级 20WJ102
学 生 孙铭蔚
指 导 教 师 刘宏伟
实 验 地 点 G712
实 验 日 期 2022.04.16
计算学部
目 录
第1章 实验基本信息....................................... - 3 -
1.1 实验目的................................................... - 3 -
1.2 实验环境与工具............................................. - 3 -
1.2.1 硬件环境............................................... - 3 -
1.2.2 软件环境............................................... - 3 -
1.2.3 开发工具............................................... - 3 -
1.3 实验预习................................................... - 3 -
第2章 实验预习........................................... - 4 -
2.1 程序优化的十大方法(5分).................................. - 4 -
2.2性能优化的方法概述(5分).................................. - 4 -
2.3 Linux下性能测试的方法(5分)............................... - 4 -
2.4 Windows下性能测试的方法(5分).............................. - 4 -
第3章 性能优化的方法..................................... - 5 -
第4章 性能优化实践....................................... - 7 -
第5章 总结.............................................. - 8 -
5.1 请总结本次实验的收获....................................... - 8 -
5.2 请给出对本次实验内容的建议................................. - 8 -
参考文献................................................. - 9 -
第1章 实验基本信息
1.1 实验目的
1.2 实验环境与工具
1.2.1 硬件环境
硬件UUID: B9297F28-81B7-5DB0-8760-89063F63E0E5
预置UDID: 00008103-001205960108801E
AMD Ryzen 7 4800H with Radeon Graphics 2.90 GHz
1.2.2 软件环境
Windows下Visual Studio 2020以上64位
1.2.3 开发工具
Visual Studio 2022 64位;vs code 64位
1.3 实验预习
第2章 实验预习
总分20分
2.1 程序优化的十大方法(5分)
2.2性能优化的方法概述(5分)
2.3 Linux下性能测试的方法(5分)
2.4 Windows下性能测试的方法(5分)
1.在visual studio中使用调试工具:性能探测器:CPU、RAM、GPU
第3章 性能优化的方法
流水线、超线程、多功能部件、分支预测投机执行、乱序执行、多核:分离的循环展开!
只有保持能够执行该操作的所有功能单元的流水线都是满的,程序才能达到这个操作的吞吐量界限
fork,每个进程负责各自的工作任务,通过mmap共享内存或磁盘等进行交互。
void putong(long img[1922][1082])
{for(int j = 1; j < 1081; j++){for (int i = 1; i < 1921;i++){/* code */img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;}}
}
源程序功能是对给定的数组模拟图像平滑算法,对数组的值进行更改
流程:任一点的颜色值为其上下左右4个点颜色的平均值,即:img[i][j] = ( img[i-1][j] + img[i+1][j] +img[i][j-1] + img[i][j+1] ) /4。
3、这个程序没有充分利用CPU,即流水线不是总处于满的状态,具有数据相关性。由于循环减少了分支预测失败的可能性,同时增加了循环体内语句并发执行的可能性,我们考虑使用循环展开对代码优化。
至少包含面向CPU、Cache的两种优化策略(20分),额外每增加1种优化方法加5分至第4章满分。
void cpu(long img[1922][1082])//循环展开{int i;long bef1,aft1,bef2,aft2;long B[1082];for (i = 0;i < 1082;i++) {B[i] = img[0][i];}for(int j=1;j<1080;j+=8){for(int i=1;i<1921;i++){bef1=img[i][j+1];aft1=img[i][j+2];bef2=img[i][j+5];aft2=img[i][j+6];img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef1)/4;img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft1+img[i][j])/4;img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef1+img[i][j+3])/4;img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft1+img[i][j+4])/4;img[i][j+4]=(B[j+4]+img[i+1][j+4]+img[i][j+3]+bef2)/4;img[i][j+5]=(B[j+5]+img[i+1][j+5]+aft2+img[i][j+4])/4;img[i][j+6]=(B[j+6]+img[i+1][j+6]+bef2+img[i][j+7])/4;img[i][j+7]=(B[j+7]+img[i+1][j+7]+aft2+img[i][j+8])/4;B[j] = img[i][j];B[j + 1] = img[i][j+1];B[j + 2] = img[i][j+2];B[j + 3] = img[i][j+3];B[j+4] = img[i][j+4];B[j + 5] = img[i][j+5];B[j + 6] = img[i][j+6];B[j + 7] = img[i][j+7];}}}
这样可以使硬件能让流水线很好地运作,即使在少数情况下也只牺牲一点效率。
void cache(long img[1922][1082]){for(int i = 1; i < 1921;i++){for (int j = 1; j < 1081; j++){/* code */img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;}}}
void fenkuai_cpu_row(long img[1922][1082]){int i, j, k, kk=4, jj=4;int bsize = 4;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1921; /* Amount that fits evenly into blocks */for (jj = 1; jj < en; jj += bsize){for (i = jj; i < jj + bsize; i++){for (j = 1; j < 1081; j++){img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;}}}}
void fenkuai_cpu_col(long img[1922][1082]){int i, j, k, kk=4, jj=4;int bsize = 4;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1081; /* Amount that fits evenly into blocks */for (jj = 1; jj < en; jj += bsize){for (i = 1; i < 1921; i++){for (j = jj; j < jj + bsize; j++){img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;}}}}
void fenkuai_cpu_row4(long img[1922][1082]){int i, j, k, kk = 4, jj = 4;int bsize = 4;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int M = 1081, N = 1921;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1921; /* Amount that fits evenly into blocks */for (int ii = 1; ii < N; ii += bsize){for (int jj = 1; jj < M; jj += bsize){for (int i = ii; i < ((ii + bsize) > N ? N : ii + bsize); i++){for (int j = jj; j < ((jj + bsize) > M ? M : jj + bsize); j++){img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j - 1] + img[i][j + 1]) / 4;}}}}}一般的优化方法(除法变成移位操作):void cache1(long img[1922][1082]){for(int j = 1; j < 1081; j++){for (int i = 1; i < 1921;i++){/* code */img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >> 2;}}}
void success(long img[1922][1082]){int i;long bef,aft;long B[1082];for (i = 0;i < 1082;i++) {B[i] = img[0][i];//存储边界值}for(int i=1;i<1921;i++){for(int j=1;j<1081;j+=4){bef=img[i][j+1];aft=img[i][j+2];img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)>>2;img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])>>2;img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])>>2;img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])>>2;B[j] = img[i][j];B[j + 1] = img[i][j+1];B[j + 2] = img[i][j+2];B[j + 3] = img[i][j+3];}}}
使用C语言中的库函数测量程序开始到结束的时间,对各个优化方法的时间进行比较,而且我每次运算后打印指定位置数据,发现均相同,证明程序没出错。
从测试结果可以看到,我采用的优化方法确实提高了程序性能,减少了程序运行时间。
采用方法描述 |
运行时间(s) |
(初始状态,没有进行任何优化,局部性很差) |
0.86 |
after (一般有用的优化,除法变为移位操作) |
0.55 |
after cache(空间局部性) |
0.78 |
after cpu(循环展开8) |
0.46 |
(整合所有非分块的优化方案) |
0.42 |
按列对矩阵进行分块(cache) |
0.80 |
按行对矩阵进行分块(cache) |
0.77 |
按列对矩阵进行分块+除法变成移位 |
0.52 |
按行对矩阵进行分块+除法变成移位 |
0.47 |
分成4*4的块(cache) |
0.42 |
4.4 结合自己计算机的硬件参数,分析优化后程序的各个参数选择依据。(15分)
我选择结合自己计算机的硬件参数,分析优化后程序的各个参数选择依据。
首先我查看了自己电脑的L1、L2、L3缓存大小,如下图所示:
void fenkuai_cpu_row128(long img[1922][1082]){int bsize = 128;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1081; /* Amount that fits evenly into blocks */int M = 1081, N = 1921;for (int jj = 1; jj < M; jj += bsize){for (int ii = 1; ii < N; ii += bsize){for (int j = jj; j < ((jj + bsize) > M ? M : jj + bsize); j++){for (int i = ii; i < ((ii + bsize) > N ? N : ii + bsize); i++){img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j - 1] + img[i][j + 1]) / 4;}}}}}
void success(long img[1922][1082]){int i;long bef,aft;long B[1082];for (i = 0;i < 1082;i++) {B[i] = img[0][i];//瀛樺偍杈圭晫鍊?}for(int i=1;i<1921;i++){for(int j=1;j<1081;j+=4){bef=img[i][j+1];aft=img[i][j+2];img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)/4;img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])/4;img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])/4;img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])/4;B[j] = img[i][j];B[j + 1] = img[i][j+1];B[j + 2] = img[i][j+2];B[j + 3] = img[i][j+3];}}}
正因为线程是调度的最小单位,控制好线程,也就相当于控制好了计算资源。
#include "stdio.h"#include<time.h>#include "math.h"long img[1922][1082];// void timecmp(long img[1922][1082])void test (long img[1922][1082]){// printf("\n");for(int k=0;k<1900;k+=500){printf("%ld\t",img[k][1000]);}printf("\n");}void putong(long img[1922][1082]){for(int j = 1; j < 1081; j++){for (int i = 1; i < 1921;i++){/* code */img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;}}}void cache1(long img[1922][1082]){for(int j = 1; j < 1081; j++){for (int i = 1; i < 1921;i++){/* code */img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >> 2;}}}void cache(long img[1922][1082]){for(int i = 1; i < 1921;i++){for (int j = 1; j < 1081; j++){/* code */img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;}}}void cpu(long img[1922][1082])//循环展开{int i;long bef,aft;long B[1082];for (i = 0;i < 1082;i++) {B[i] = img[0][i];//存储边界值}for(int j=1;j<1080;j+=4){for(int i=1;i<1921;i++){bef=img[i][j+1];aft=img[i][j+2];img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)/4;img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])/4;img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])/4;img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])/4;B[j] = img[i][j];B[j + 1] = img[i][j+1];B[j + 2] = img[i][j+2];B[j + 3] = img[i][j+3];}}}void fenkuai_cpu_row(long img[1922][1082]){int i, j, k, kk=4, jj=4;int bsize = 4;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1921; /* Amount that fits evenly into blocks */for (jj = 1; jj < en; jj += bsize){for (i = jj; i < jj + bsize; i++){for (j = 1; j < 1081; j++){img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;}}}}void fenkuai_cpu_row_yi(long img[1922][1082]){int i, j, k, kk=4, jj=4;int bsize = 4;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1921; /* Amount that fits evenly into blocks */for (jj = 1; jj < en; jj += bsize){for (i = jj; i < jj + bsize; i++){for (j = 1; j < 1081; j++){img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >>2;}}}}void fenkuai_cpu_col(long img[1922][1082]){int i, j, k, kk=4, jj=4;int bsize = 4;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1081; /* Amount that fits evenly into blocks */for (jj = 1; jj < en; jj += bsize){for (i = 1; i < 1921; i++){for (j = jj; j < jj + bsize; j++){img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;}}}}void fenkuai_cpu_col_yi(long img[1922][1082]){int i, j, k, kk=4, jj=4;int bsize = 4;// int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */int en = 1081; /* Amount that fits evenly into blocks */for (jj = 1; jj < en; jj += bsize){for (i = 1; i < 1921; i++){for (j = jj; j < jj + bsize; j++){img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >>2;}}}}void success(long img[1922][1082]){int i;long bef,aft;long B[1082];for (i = 0;i < 1082;i++) {B[i] = img[0][i];//存储边界值}for(int i=1;i<1921;i++){for(int j=1;j<1081;j+=4){bef=img[i][j+1];aft=img[i][j+2];img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)>>2;img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])>>2;img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])>>2;img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])>>2;B[j] = img[i][j];B[j + 1] = img[i][j+1];B[j + 2] = img[i][j+2];B[j + 3] = img[i][j+3];}}}int main (){printf("startle!\n");int i = 0;for(int i=0;i<1922;i++){for (int j = 0; j < 1082; j++){/* code */img[i][j]= i+j;}}clock_t start_t = clock();for(i=0;i<50;i++)putong(img);clock_t end_t = clock();test(img);double sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("(初始状态,没有进行任何优化,局部性很差)cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)cache1(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("after (一般有用的优化,除法变为移位操作)cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)cache(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("after cache(空间局部性) cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)cpu(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("after cpu(循环展开) cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)success(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("(整合所有非分块的优化方案)cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)fenkuai_cpu_col(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("(分块col)cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)fenkuai_cpu_row(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("(分块row)cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)fenkuai_cpu_col_yi(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("(分块col+移位)cost time: %f(s)\n",sum_time);start_t = clock();for(i=0;i<50;i++)fenkuai_cpu_row_yi(img);end_t = clock();test(img);sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;printf("(分块row+移位)cost time: %f(s)\n",sum_time);}
第5章 总结
5.1 请总结本次实验的收获
5.2 请给出对本次实验内容的建议
实验内容很好,就是某些问题描述不清,例如4.4题,没有给出操作实例,可能导致很多学生不知道从何做起,希望能改进这一点,其余做的都很好。
参考文献
[1] 林来兴. 空间控制技术[M]. 北京:中国宇航出版社,1992:25-42.
[2] 辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.
[4] 谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.
[5] KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.
哈工大csapp-LAB3程序优化相关推荐
- 哈工大csapp lab3
计算机系统实验报告 1 - 实验报告 实 验(三) 题 目 Binary Bomb 二进制炸弹 专 业 计算学部 学 号 190110812 班 级 7 学 生 刘新晨 指 导 教 师 吴锐 实 验 ...
- 【读薄 CSAPP】贰 机器指令与程序优化
[读薄 CSAPP]贰 机器指令与程序优化 文章目录 [读薄 CSAPP]贰 机器指令与程序优化 学习目标 基础知识 从 8086 到 Core i7 从 C 到机器代码 汇编入门 流程控制 条件代码 ...
- CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom
CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom 栈结构镇楼 这里先给 ...
- 中国电子学会图形化四级编程题:程序优化
「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 我们将有关编程题目的教学视频已经发布到抖 ...
- 【青少年编程】【四级】绘图程序优化
「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 微信后台回复"资料下载&quo ...
- ESP32检测调制激光信号程序优化
▌01 调制激光检测 1.裁判系统要求 在 测试ESP32S基本模块的功能,并验证是否可以应用在AI智能车竞赛检测激光信号中 测试了基于 ESP32 模块来检测 全国大学生智能车竞赛 中的 室内AI视 ...
- 推荐CUDA程序优化的15个策略
推荐CUDA程序优化的15个策略 0条评论 2011-07-06 09:48 来源:潇湘学子岳麓生的博客 作者: 潇湘学子岳麓生 编辑: 王玉圆 [IT168 技术]在<CUDA程序优化策略 ...
- CUDA程序优化技巧
CUDA程序优化技巧 2013-11-18 23:41 1469人阅读 评论(4) 收藏 举报 分类: CUDA(24) 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 有如下 ...
- CUDA学习笔记之程序优化
CUDA学习笔记之程序优化 标签: cuda优化conflict存储算法数学计算 2010-01-05 17:18 5035人阅读 评论(4) 收藏 举报 分类: CUDA(6) 版权声明:本文为博主 ...
最新文章
- java jdbc工具类抽取_JavaWeb入门(三):JDBC工具类的抽取
- 开源Gis简介(转)
- html用户登录界面开源代码_Toolkit Pro助力企业开专业且强大的图形用户界面,抢占市场先机...
- vue2.0组件之间的通信
- ping的实现和代码分析
- 【坑爹微信】总有一款接口能坑你到吐血 --- 微信开发经验录
- volume 生命周期管理 - 每天5分钟玩转 Docker 容器技术(44)
- centos模拟post请求_java模拟post和get请求(2019/10/25)
- 8.0服务器维护时间,魔兽世界8.0服务器维护把玩家心态搞崩 网友:喜闻乐见
- 教你如何在机器学习竞赛中更胜一筹(上)
- TServerSocket阻塞模式下Request-Response编程框架
- 如何解决卸载McAfee时出现“处于托管模式时无法删除”问题(转)
- GLM 中的mat4
- 无线路由器服务器连接线,无线路由器连接有线路由器怎么设置?
- 如何VUE写桌面应用(electron)
- 【k.11】python+appium+雷电模拟器 app自动化测试 demo 教学
- 强化学习导论_Example 6.5: Windy Grid-world
- obj转stl_STL转STP的方法视频教程,OBJ格式转STP或者IGS开模具格式的过程,STL转STP软件介绍...
- 人类最常见的25个认知偏误(一)
- c语音删除字符数组中的元素
热门文章
- android Telephony学习 --- 第七篇 android7.0 来电(MT)流程
- 详解301永久重定向实现方法
- 名画97 金大受《十六罗汉图》
- ai物联网工程师_如何将Api.ai助手连接到物联网
- C语言实现傅里叶变化算法
- 网络编程——The C10K Problem(C10K = connection 10 kilo 问题)。k 表示 kilo,即 1000
- vof模型matlab程序,Fluent学习笔记(11)----VOF模型
- Docker知识五:服务编排(Docker Compose概念)
- Gutenberg 5.8发布了基于块的新小部件屏幕原型
- pdf转word免费