zoukankan      html  css  js  c++  java
  • optimization blocks (csapp chapter 5.1)

    p_511

    编译器在没有指示下,会做‘ safe optimization',因此有些优化在没有参数的指示下是不会对代码做优化的,故在程序中应该避免某一类代码,因为它们妨碍了编译器做优化。

    optimization blocks: aspects of programs that can severely limit the opportunities for a compiler to generate optimized code;

    两类optimization blocks:

    1、memory aliasing

     pointers may generate the same memory location is known as memory aliasing. In performing only safe optimizations, the compiler must assume that different pointers may be aliased, limiting the set of possible optimizations.

    // from cmu
    /* Sum rows is of n X n matrix a
       and store in vector b  */
    void sum_rows1(int  *a, int  *b, int n) {
        int i, j;
        for (i = 0; i < n; i++) {
        b[i] = 0;
        for (j = 0; j < n; j++)
            b[i] += a[i*n + j];
        }
    }
    
    /*如果我们调用时为
      int A[9];
      int* B = A + 3;
      sum_rows1(A, B);
      如果编译器将其优化成如下类的形式,显然有背原意
       void sum_rows2(int *a, int *b, int n) {
        int i, j;
        for (i = 0; i < n; i++) {
        double val = 0;
        for (j = 0; j < n; j++)
            val += a[i*n + j];
             b[i] = val;
        }
    }*/

    /* 简化了 sum_rows1: .L4: movl %ebp, %ecx movl $0, (%edx,%ebp,4) movl $0, %eax .L3: movl (%esi,%eax,4), %ebx ;(%esi, %eax, 4) : &a[i*n + j] addl %ebx, (%edx,%ecx,4) ;(%edx, %ecx, 4) : &b[i] addl $1, %eax ;%eax : j cmpl %edi, %eax ;%edi : n jne .L3 addl $1, %ebp ;%ebp : i addl (%esp), %esi cmpl %edi, %ebp jne .L4 */
    //书上例子
    //当xp = yp时,twiddle1 与 twiddle2显然不同,因此编译器不会做一些优化,以免将twiddle1优化成与twiddle2相同的功能函数
    void twiddle1(int *xp, int* yp)
    {
         *xp += *yp;
         *xp += *yp;   
    }
    
    void twiddle2(int *xp, int* yp)
    {
          *xp += 2* *yp;
    }

    2、procedure calls

        Most compilers do not try to determine whether a function is free of side effects and hence is a candidate for optimizations.Instead, the compiler assumes the worst case and leaves function call intact(原封不动)

    //经典(from cmu)
    void lower(char* s)
    {
          int i = 0;
          for (i = 0; i < strlen(s); i++)
                if(s[i] >= 'A' && s[i] <= 'Z')
                      s[i] -= ('A' - 'a');      
    }
    
    //编译器为何不把strlen(s)提取出来,作为一个临时量,这样就可以减少函数调用了?
    
    //Why couldn’t compiler move strlen out of  inner loop?
    //      (1)Procedure may have side effects
    //                 Alters global state each time called
    //       (2)Function may not return same value for given arguments
    //                  Depends on other parts of global state
    //                  Procedure lower could interact with strlen
    
    //Warning:1)Compiler treats procedure call as a black box
              (2)Weak optimizations near them
    //书上的例子
    int f(void);
    
    int func1(void)
    {
         return f() + f() + f() + f();
    //procedure call不可优化成4*f(), 否则就错了
    }
    
    int func2(void)
    {
         return 4 * f();   
    }
    
    int counter = 0;
    
    int f(void)
    {
         return counter++;
    }
  • 相关阅读:
    单 GPU 程序 转 多 GPU 程序
    Ubuntu 开启ssh 连接,设置静态 ip 地址。
    Ubuntu 添加新硬盘 之 分区+格式化+挂载
    夜间模式的开启与关闭,父模板的制作
    开始Flask项目
    完成登录与注册页面的前端
    JavaScript 基础,登录前端验证
    CSS实例:图片导航块
    导航,头部,CSS基础
    web基础,用html元素制作web页面
  • 原文地址:https://www.cnblogs.com/openix/p/3199264.html
Copyright © 2011-2022 走看看