免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: system888net
打印 上一主题 下一主题

两段完成同样功能的简单C代码 [复制链接]

论坛徽章:
0
41 [报告]
发表于 2008-03-26 16:04 |只看该作者
code1:
int f(int x)
{
  int y;
  switch(x) {
  case 0:
     y=8;
  break;
  case 1:
     y=6;
  break;
  case 2:
     y=7;
  break;
  case 3:
     y=4;
  break;
  case 4:
     y=11;
  break;
  case 5:
     y=12;
  break;
  case 6:
     y=88;
  break;
  default:
     y=x*x;
  break;
  };
  return(y);
}



int main()
{
    int x,y;

    x=11;
    y=f(x);
    return(0);
}

对应的 asm :
        .file        "test1.cpp"
        .text
        .align 2
.globl _Z1fi
        .type        _Z1fi,@function
_Z1fi:
.LFB9:
        pushl        %ebp
.LCFI0:
        movl        %esp, %ebp
.LCFI1:
        subl        $4, %esp
.LCFI2:
        cmpl        $6, 8(%ebp)
        ja        .L10
        movl        8(%ebp), %eax
        sall        $2, %eax
        movl        .L11(%eax), %eax
        jmp        *%eax
        .section        .rodata
        .align 4
        .align 4
.L11:
        .long        .L3
        .long        .L4
        .long        .L5
        .long        .L6
        .long        .L7
        .long        .L8
        .long        .L9
        .text
.L3:
        movl        $8, -4(%ebp)
        jmp        .L2
.L4:
        movl        $6, -4(%ebp)
        jmp        .L2
.L5:
        movl        $7, -4(%ebp)
        jmp        .L2
.L6:
        movl        $4, -4(%ebp)
        jmp        .L2
.L7:
        movl        $11, -4(%ebp)
        jmp        .L2
.L8:
        movl        $12, -4(%ebp)
        jmp        .L2
.L9:
        movl        $88, -4(%ebp)
        jmp        .L2
.L10:
        movl        8(%ebp), %eax
        imull        8(%ebp), %eax
        movl        %eax, -4(%ebp)
.L2:
        movl        -4(%ebp), %eax
        leave
        ret
.LFE9:
.Lfe1:
        .size        _Z1fi,.Lfe1-_Z1fi
        .align 2
.globl main
        .type        main,@function
main:
.LFB11:
        pushl        %ebp
.LCFI3:
        movl        %esp, %ebp
.LCFI4:
        subl        $8, %esp
.LCFI5:
        andl        $-16, %esp
        movl        $0, %eax
        subl        %eax, %esp
        movl        $11, -4(%ebp)
        subl        $12, %esp
        pushl        -4(%ebp)
.LCFI6:
        call        _Z1fi
        addl        $16, %esp
        movl        %eax, -8(%ebp)
        movl        $0, %eax
        leave
        ret
.LFE11:
.Lfe2:
        .size        main,.Lfe2-main
        .ident        "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"

论坛徽章:
0
42 [报告]
发表于 2008-03-26 16:06 |只看该作者
code2:

int f(int x)
{
  int y;
  if(x==0)
  {
     y=8;
  }
  else if(x==1)
  {
     y=6;
  }
  else if(x==2)
  {
     y=7;
  }
  else if(x==3)
  {
     y=4;
  }
  else if(x==4)
  {
     y=11;
  }
  else if(x==5)
  {
     y=12;
  }
  else if(x==6)
  {
     y=88;
  }
  else
  {
     y=x*x;
  }
  return(y);
}



int main()
{
    int x,y;

    x=11;
    y=f(x);
    return(0);
}

对应的asm:

        .file        "test2.cpp"
        .text
        .align 2
.globl _Z1fi
        .type        _Z1fi,@function
_Z1fi:
.LFB9:
        pushl        %ebp
.LCFI0:
        movl        %esp, %ebp
.LCFI1:
        subl        $4, %esp
.LCFI2:
        cmpl        $0, 8(%ebp)
        jne        .L2
        movl        $8, -4(%ebp)
        jmp        .L3
.L2:
        cmpl        $1, 8(%ebp)
        jne        .L4
        movl        $6, -4(%ebp)
        jmp        .L3
.L4:
        cmpl        $2, 8(%ebp)
        jne        .L6
        movl        $7, -4(%ebp)
        jmp        .L3
.L6:
        cmpl        $3, 8(%ebp)
        jne        .L8
        movl        $4, -4(%ebp)
        jmp        .L3
.L8:
        cmpl        $4, 8(%ebp)
        jne        .L10
        movl        $11, -4(%ebp)
        jmp        .L3
.L10:
        cmpl        $5, 8(%ebp)
        jne        .L12
        movl        $12, -4(%ebp)
        jmp        .L3
.L12:
        cmpl        $6, 8(%ebp)
        jne        .L14
        movl        $88, -4(%ebp)
        jmp        .L3
.L14:
        movl        8(%ebp), %eax
        imull        8(%ebp), %eax
        movl        %eax, -4(%ebp)
.L3:
        movl        -4(%ebp), %eax
        leave
        ret
.LFE9:
.Lfe1:
        .size        _Z1fi,.Lfe1-_Z1fi
        .align 2
.globl main
        .type        main,@function
main:
.LFB11:
        pushl        %ebp
.LCFI3:
        movl        %esp, %ebp
.LCFI4:
        subl        $8, %esp
.LCFI5:
        andl        $-16, %esp
        movl        $0, %eax
        subl        %eax, %esp
        movl        $11, -4(%ebp)
        subl        $12, %esp
        pushl        -4(%ebp)
.LCFI6:
        call        _Z1fi
        addl        $16, %esp
        movl        %eax, -8(%ebp)
        movl        $0, %eax
        leave
        ret
.LFE11:
.Lfe2:
        .size        main,.Lfe2-main
        .ident        "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"

论坛徽章:
0
43 [报告]
发表于 2008-03-26 16:38 |只看该作者
code3code1的非连续x)


int f(int x)
{
  int y;
  switch(x) {
  case 0:
     y=8;
  break;
  case 88:
     y=6;
  break;
  case 111:
     y=7;
  break;
  case 211:
     y=4;
  break;
  case 333:
     y=11;
  break;
  case 555:
     y=12;
  break;
  case 688:
     y=88;
  break;
  default:
     y=x*x;
  break;
  };
  return(y);
}



int main()
{
    int x,y;

    x=11;
    y=f(x);
    return(0);
}

对应的asm:

        .file        "test3.cpp"
        .text
        .align 2
.globl _Z1fi
        .type        _Z1fi,@function
_Z1fi:
.LFB9:
        pushl        %ebp
.LCFI0:
        movl        %esp, %ebp
.LCFI1:
        subl        $8, %esp
.LCFI2:
        movl        8(%ebp), %eax
        movl        %eax, -8(%ebp)
        cmpl        $211, -8(%ebp)
        je        .L6
        cmpl        $211, -8(%ebp)
        jg        .L12
        cmpl        $88, -8(%ebp)
        je        .L4
        cmpl        $88, -8(%ebp)
        jg        .L13
        cmpl        $0, -8(%ebp)
        je        .L3
        jmp        .L10
.L13:
        cmpl        $111, -8(%ebp)
        je        .L5
        jmp        .L10
.L12:
        cmpl        $555, -8(%ebp)
        je        .L8
        cmpl        $555, -8(%ebp)
        jg        .L14
        cmpl        $333, -8(%ebp)
        je        .L7
        jmp        .L10
.L14:
        cmpl        $688, -8(%ebp)
        je        .L9
        jmp        .L10
.L3:
        movl        $8, -4(%ebp)
        jmp        .L2
.L4:
        movl        $6, -4(%ebp)
        jmp        .L2
.L5:
        movl        $7, -4(%ebp)
        jmp        .L2
.L6:
        movl        $4, -4(%ebp)
        jmp        .L2
.L7:
        movl        $11, -4(%ebp)
        jmp        .L2
.L8:
        movl        $12, -4(%ebp)
        jmp        .L2
.L9:
        movl        $88, -4(%ebp)
        jmp        .L2
.L10:
        movl        8(%ebp), %eax
        imull        8(%ebp), %eax
        movl        %eax, -4(%ebp)
.L2:
        movl        -4(%ebp), %eax
        leave
        ret
.LFE9:
.Lfe1:
        .size        _Z1fi,.Lfe1-_Z1fi
        .align 2
.globl main
        .type        main,@function
main:
.LFB11:
        pushl        %ebp
.LCFI3:
        movl        %esp, %ebp
.LCFI4:
        subl        $8, %esp
.LCFI5:
        andl        $-16, %esp
        movl        $0, %eax
        subl        %eax, %esp
        movl        $11, -4(%ebp)
        subl        $12, %esp
        pushl        -4(%ebp)
.LCFI6:
        call        _Z1fi
        addl        $16, %esp
        movl        %eax, -8(%ebp)
        movl        $0, %eax
        leave
        ret
.LFE11:
.Lfe2:
        .size        main,.Lfe2-main
        .ident        "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"

论坛徽章:
0
44 [报告]
发表于 2008-03-26 17:14 |只看该作者

回复 #43 system888net 的帖子

code3 的汇编有点怪:
        cmpl        $211, -8(%ebp)
        je        .L6
        cmpl        $211, -8(%ebp)
        jg        .L12
为何重复比较,不明白?

论坛徽章:
0
45 [报告]
发表于 2008-03-26 19:06 |只看该作者
原帖由 alickexu 于 2008-3-26 15:32 发表
都不高,不如写成:

int switch(int x)
{
    int SwitchTbl[4] = {0, 1, 6, 2, 8}
    return (x >= 4) ? f(x) : SwitchTbl[x];
}


加个static就更好了,呵呵、、

论坛徽章:
0
46 [报告]
发表于 2008-03-26 21:56 |只看该作者
原帖由 chzCPU 于 2008-3-26 17:14 发表
code3 的汇编有点怪:
        cmpl        $211, -8(%ebp)
        je        .L6
        cmpl        $211, -8(%ebp)
        jg        .L12
为何重复比较,不明白?

是啊为何重复比较,是gcc 优化的问题?

哪位大侠给提示一下?

[ 本帖最后由 newIT666 于 2008-3-26 21:59 编辑 ]

论坛徽章:
0
47 [报告]
发表于 2008-03-26 22:05 |只看该作者
原帖由 agaric 于 2008-3-25 10:36 发表
这个问题没有意义,这两种都不是好的代码,有更好的方法。
有种方法叫做表驱动,做为程序员应当掌握。


如果表很大怎么办?cache命中率会不高的。
稀疏表呢?

论坛徽章:
0
48 [报告]
发表于 2008-03-26 22:48 |只看该作者
原帖由 prolj 于 2008-3-26 22:05 发表


如果表很大怎么办?cache命中率会不高的。
稀疏表呢?


这根cache命中有什么关系,就这个问题查表必然比判断语句来的快,毋庸置疑的。深入理解计算机系统看多了吧。

当然,不是所有类似的问题都可以用表来解决,不然还需要其他高级数据结构来干什么。

[ 本帖最后由 agaric 于 2008-3-26 22:50 编辑 ]

论坛徽章:
0
49 [报告]
发表于 2008-03-27 10:38 |只看该作者
原帖由 chzCPU 于 2008-3-26 17:14 发表
code3 的汇编有点怪:
        cmpl        $211, -8(%ebp)
        je        .L6
        cmpl        $211, -8(%ebp)
        jg        .L12
为何重复比较,不明白?


按你的想法写成这样:
        cmpl        $211, -8(%ebp)
        je        .L6
        jg        .L12
能正确运行?

论坛徽章:
0
50 [报告]
发表于 2008-03-27 12:02 |只看该作者
原帖由 agaric 于 2008-3-26 22:48 发表
这根cache命中有什么关系,就这个问题查表必然比判断语句来的快,毋庸置疑的。深入理解计算机系统看多了吧。

当然,不是所有类似的问题都可以用表来解决,不然还需要其他高级数据结构来干什么。


case套case你知道不?
你认为跟cache没关系的话就没关系好了 ,你不适合做优化。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP