优化实验 Optimize( 二 )

  • COMVxx指令
    1. 原理:代替test/cmp+jxx,减少条件的判断,直接实现功能
    2. 实现方案:利用指令CMOVxx代替test/cmp + jxx
  • 使用编译器的优化模式,-O:0 1 2 3
    1. 面向编译器的优化 。
    2. 期望编译器能提高速度或者能够节省内存,对程序进行有偏向性的编译 。
  • 多线程优化
    1. 面向CPU的优化,利用CPU多核的性质,将任务分为多个线程
    2. 多线程与多进程的区别:
      1. 线程是进程的子集,一个进程可能由多个线程组成
      2. 多进程的数据是分开的,共享复杂 。比如你可以一边听歌,一边玩游戏,实际上CPU在不断切换地工作,只是太快感觉不出来 。
      3. 多线程共享进程数据,共享简单 。
  • 嵌入式汇编
    1. 原理:通过汇编语言更接近底层,通过对底层直接操作,防止编译器编译出一些冗繁的操作,省去一些不必要的判断
    2. 实现方案:利用嵌入汇编的方法,人为的对底层进行优化
  • 减少除法等一些计算量大的运算的使用
    1. 用移位代替乘除法 。
    2. 能用乘法就不用除法:
      //test1while(a > b / c)// 1.1while(a * c > b)// 1.2//test2 取模运算a = a % b//2.1while(a >= b) //2.2{ a -= b;}
  • GPU编程
    1. 原理:利用GPU多核的特点,拥有更强的算力,可以更快的完成任务
    2. 实现方案:利用GPU运行程序
  • 多进程优化
    1. 使用LinuxC语言fork函数
    2. 一个进程,包括代码、数据和分配给进程的资源 。fork ( )函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事 。
      一个进程调用 fork( )函数后,系统先给新的进程分配资源,例如存储数据和代码的空间 。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同 。相当于克隆了一个自己 。
    3. fork函数参考链接:fork函数
  • 优化实验实验任务? 一个图像处理程序实现图像的平滑,其图像分辨率为1920*1080,每一点颜色值为64b,用long img [1920] [1080]存储屏幕上的所有点颜色值,颜色值可从0依行列递增,或真实图像 。
    平滑算法为:任一点的颜色值为其上下左右4个点颜色的平均值,即:
    ?img[i] [j] =(img [i-1] [j] +img[i+1] [j]+img[i] [j-1] +img[i] [j+1] ) / 4 。
    请面向你的CPU与cache,利用本课程学过的优化技术,编写程序,并说明你所采用的优化方法 。
    前言关于本次的平滑算法: 不考虑四周,不考虑前后变量改变带来的正确性问题,只作为优化的任务 。
    【优化实验 Optimize】但如果考虑其正确性,用一个 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; }}

    经验总结扩展阅读