- 原理:通过汇编语言更接近底层,通过对底层直接操作,防止编译器编译出一些冗繁的操作,省去一些不必要的判断
- 实现方案:利用嵌入汇编的方法,人为的对底层进行优化
- 用移位代替乘除法 。
- 能用乘法就不用除法:
//test1while(a > b / c)// 1.1while(a * c > b)// 1.2//test2 取模运算a = a % b//2.1while(a >= b) //2.2{ a -= b;}
- 原理:利用GPU多核的特点 , 拥有更强的算力 , 可以更快的完成任务
- 实现方案:利用GPU运行程序
- 使用LinuxC语言fork函数
一个进程,包括代码、数据和分配给进程的资源 。fork ( )函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事 , 但如果初始参数或者传入的变量不同 , 两个进程也可以做不同的事 。
一个进程调用 fork( )函数后,系统先给新的进程分配资源,例如存储数据和代码的空间 。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同 。相当于克隆了一个自己 。
- fork函数参考链接:fork函数
平滑算法为:任一点的颜色值为其上下左右4个点颜色的平均值,即:
?img[i] [j] =(img [i-1] [j] +img[i+1] [j]+img[i] [j-1] +img[i] [j+1] ) / 4 。
请面向你的CPU与cache,利用本课程学过的优化技术,编写程序 , 并说明你所采用的优化方法 。
前言关于本次的平滑算法: 不考虑四周 , 不考虑前后变量改变带来的正确性问题 , 只作为优化的任务 。
但如果考虑其正确性,用一个 dst [1920]] [1080] 存储平滑后的图像值也是可以的 。
测量性能使用C语言 time.h 库, 获取运行前后时间钟,算出运行时间 。
void Test(void (*function)()){ clock_t t1 = clock(); int t = 100; while(t--) {function(); } clock_t t2 = clock(); printf("COST %ldms\n",(t2 - t1) * 1000 / CLOCKS_PER_SEC);}
原始版本先要写为可优化的版本,所以先枚举列再枚举行 。int i, j;for(j = 1; j < WIDTH - 1; j ++ ){ for(i = 1; i < HEIGHT - 1; i ++ ) {img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j + 1] + img[i][j - 1]) / 4; }}
面向cache优化改为先枚举行,再枚举列 。int i, j;for(i = 1; i < HEIGHT - 1; i ++ ){ for(j = 1; j < WIDTH - 1; j ++ ) {img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j + 1] + img[i][j - 1]) / 4; }}
循环展开减少迭代次数 。但是实验结果是性能并没有优化(相比较上一个) 。原因应该是:前后变量有运算依赖关系 。
int block = 4;int i, j;for(i = 1; i < HEIGHT - 1; i ++ ){ for(j = 1; j < WIDTH - 4; j += block) {img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j + 1] + img[i][j - 1]) / 4;img[i][j + 1] = (img[i - 1][j + 1] + img[i + 1][j + 1] + img[i][j + 1 + 1] + img[i][j - 1 + 1]) / 4;img[i][j + 2] = (img[i - 1][j + 2] + img[i + 1][j + 2] + img[i][j + 1 + 2] + img[i][j - 1 + 2]) / 4;img[i][j + 3] = (img[i - 1][j + 3] + img[i + 1][j + 3] + img[i][j + 1 + 3] + img[i][j - 1 + 3]) / 4; } for(;j < WIDTH - 1; j ++ ) {img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j + 1] + img[i][j - 1]) / 4; }}
并发优化既然前后变量有运算依赖关系,那我们就不让有依赖关系,并保持循环展开的形式 。但实验结果是:没有优化多少,这个原因仍没搞懂 , 或许需要查看汇编代码 。
int i, j;//为什么是14:14|1918for(i = 1; i < HEIGHT - 1; i ++ ){ for(j = 1; j < WIDTH - 1; j += 14) {img[i][j + 0] = (img[i - 1][j] + img[i + 1][j] + img[i][j + 1] + img[i][j - 1]) / 4;img[i][j + 2] = (img[i - 1][j + 2] + img[i + 1][j + 2] + img[i][j + 1 + 2] + img[i][j - 1 + 2]) / 4;img[i][j + 4] = (img[i - 1][j + 4] + img[i + 1][j + 4] + img[i][j + 1 + 4] + img[i][j - 1 + 4]) / 4;img[i][j + 6] = (img[i - 1][j + 6] + img[i + 1][j + 6] + img[i][j + 1 + 6] + img[i][j - 1 + 6]) / 4;img[i][j + 8] = (img[i - 1][j + 8] + img[i + 1][j + 8] + img[i][j + 1 + 8] + img[i][j - 1 + 8]) / 4;img[i][j + 10] = (img[i - 1][j + 10] + img[i + 1][j + 10] + img[i][j + 1 + 10] + img[i][j - 1 + 10]) / 4;img[i][j + 12] = (img[i - 1][j + 12] + img[i + 1][j + 12] + img[i][j + 1 + 12] + img[i][j - 1 + 12]) / 4; } for(j = 2; j < WIDTH - 1; j += 14) {img[i][j + 0] = (img[i - 1][j] + img[i + 1][j] + img[i][j + 1] + img[i][j - 1]) / 4;img[i][j + 2] = (img[i - 1][j + 2] + img[i + 1][j + 2] + img[i][j + 1 + 2] + img[i][j - 1 + 2]) / 4;img[i][j + 4] = (img[i - 1][j + 4] + img[i + 1][j + 4] + img[i][j + 1 + 4] + img[i][j - 1 + 4]) / 4;img[i][j + 6] = (img[i - 1][j + 6] + img[i + 1][j + 6] + img[i][j + 1 + 6] + img[i][j - 1 + 6]) / 4;img[i][j + 8] = (img[i - 1][j + 8] + img[i + 1][j + 8] + img[i][j + 1 + 8] + img[i][j - 1 + 8]) / 4;img[i][j + 10] = (img[i - 1][j + 10] + img[i + 1][j + 10] + img[i][j + 1 + 10] + img[i][j - 1 + 10]) / 4;img[i][j + 12] = (img[i - 1][j + 12] + img[i + 1][j + 12] + img[i][j + 1 + 12] + img[i][j - 1 + 12]) / 4; }}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- dp优化 | 各种dp优化方式例题精选
- 基于PL022 SPI 控制器 海思3516系列芯片SPI速率慢问题深入分析与优化
- 二 网络工程知识VLAN的基础和配置:802.1q帧;Access、Trunk、Hybrid接口工作模式过程与配置;VLANIF的小实验
- 京东云TiDB SQL优化的最佳实践
- Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化
- NodeJS 服务 Docker 镜像极致优化指北
- 如何做谷歌SEO优化 淘宝谷歌搜索优化
- AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
- Apache Dolphin Scheduler 3.0.1 发布,对核心及UI相关进行优化
- AVX图像算法优化系列一: 初步接触AVX。