免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6521 | 回复: 13
打印 上一主题 下一主题

[C] [讨论]浮点运算展开的问题,效率提高比我想象的还多 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-22 16:55 |只看该作者 |倒序浏览
测试浮点数的加法,用下面两个小程序
>cat t.c  这个程序没有优化
int main(void){
double a=0.1f,sum=0.0f;
int i;
for(i=0;i<1024000000;++i){
sum+=a;
}
}
>gcc t.c
>time a.out
real 0m1.363s
user 0m1.152s
sys 0m0.032s
--------------------------------
然后一个优化的版本
>cat t2.c
int main(void){
double a=0.1f,sum,sum1,sum2,sum3,sum4;
sum=sum1=sum2=sum3=sum4=0.0f;
int i;
for(i=0;i<250000000;i++){
sum1+=a;
sum2+=a;
sum3+=a;
sum4+=a;
}
sum+=sum1;
sum+=sum2;
sum+=sum3;
sum+=sum4;
}
>gcc t2.c -o a.out.fast
>time ./a.out.fast
real 0m0.273s
user 0m0.0216s
sys 0m0.016s
--------------------------------
这个数字让我很惊讶,我原本认为用4路标量优化这个浮点加法,性能的提高应该是<4的才对,而现在确>4
看起来t.c里面1024M次比较,自增和加法。t2.c里面256M次比较和自增,1024M次加法,速度提高不应该超过4倍的。只运行一条指令,浮点加法运算比自增和比较耗时更多吧?

好像这个优化方法有点无敌了,但是自己又无法解释。
想听听各位大虾的高见,我这里抛砖引玉了!

[ 本帖最后由 jeanlove 于 2008-10-23 10:27 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-10-22 18:00 |只看该作者
能解释一下上面这个现象么?
谢谢

论坛徽章:
0
3 [报告]
发表于 2008-10-22 20:13 |只看该作者
贴汇编代码出来吧
gcc -S 生成汇编代码

论坛徽章:
0
4 [报告]
发表于 2008-10-23 00:04 |只看该作者
1. 要注意说明测试的CPU
2. 浮点的运算是在FPU里进行的,而循环的代码是在CPU里运行的,进行的是整型的运算.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
5 [报告]
发表于 2008-10-23 09:13 |只看该作者
测程序运行时间,用gprof可能效果更好

论坛徽章:
0
6 [报告]
发表于 2008-10-23 09:43 |只看该作者
硬件可能对浮点运算进行优化了

论坛徽章:
0
7 [报告]
发表于 2008-10-23 10:08 |只看该作者
按照楼上dx说的,电脑的配置和汇编的结果都贴出来了。以前学汇编的时候没关注过浮点运算,还请指点。
-------------------------------------
computer: Dell D520 笔记本
cpu         : Intel core2duo 1.66G
mem       : 1G 667MHz
-------------------------------------
>cat t.s
        .file   "t.c"
        .section        .rodata
        .align 8
.LC0:
        .long   -1610612736
        .long   1069128089
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $36, %esp
        fldl    .LC0
        fstpl   -32(%ebp)
        fldz
        fstpl   -24(%ebp)
        movl    $0, -12(%ebp)
        jmp     .L2
.L3:
        fldl    -24(%ebp)
        faddl   -32(%ebp)
        fstpl   -24(%ebp)
        incl    -12(%ebp)
.L2:
        cmpl    $1023999999, -12(%ebp)
        jle     .L3
        addl    $36, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)"        .section        .note.GNU-stack,"",@progbits
------------------------------
>cat t2.s
        .file   "t2.c"
        .section        .rodata
        .align 8
.LC0:
        .long   -1610612736
        .long   1069128089
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $52, %esp
        fldl    .LC0
        fstpl   -56(%ebp)
        fldz
        fstpl   -24(%ebp)
        fldl    -24(%ebp)
        fstpl   -32(%ebp)
        fldl    -32(%ebp)
        fstpl   -40(%ebp)
        fldl    -40(%ebp)
        fstpl   -48(%ebp)
        movl    $0, -12(%ebp)
        jmp     .L2
.L3:
        fldl    -48(%ebp)
        faddl   -56(%ebp)
        fstpl   -48(%ebp)
        incl    -12(%ebp)
.L2:
        cmpl    $255999999, -12(%ebp)
        jle     .L3
        fldl    -40(%ebp)
        faddl   -56(%ebp)
        fstpl   -40(%ebp)
        fldl    -32(%ebp)
        faddl   -56(%ebp)
        fstpl   -32(%ebp)
        fldl    -24(%ebp)
        faddl   -56(%ebp)
        fstpl   -24(%ebp)
        addl    $52, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)"        .section        .note.GNU-stack,"",@progbits

[ 本帖最后由 jeanlove 于 2008-10-23 10:21 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2008-10-23 10:25 |只看该作者
从汇编的结果来看,我的for循环里面的内容虽然不一样,但是.L3得到的内容却是一样的
for(i=0;i<1024000000;++i){
sum+=a;
}

for(i=0;i<250000000;i++){
sum1+=a;
sum2+=a;
sum3+=a;
sum4+=a;
}
似乎都是对应着.L3的一次浮点运算
.L3:
        fldl    -24(%ebp)
        faddl   -32(%ebp)
        fstpl   -24(%ebp)
        incl    -12(%ebp)

.L3:
        fldl    -48(%ebp)
        faddl   -56(%ebp)
        fstpl   -48(%ebp)
        incl    -12(%ebp)
奇怪了,难道第二个for里面的4次浮点加法,其实只做了一个? 没道理啊

论坛徽章:
0
9 [报告]
发表于 2008-10-23 15:59 |只看该作者
奇怪:第二个for里面的4次浮点加法,其实只做了一个?

还请大虾给个解释啊!在线等!

论坛徽章:
0
10 [报告]
发表于 2008-10-23 16:15 |只看该作者
我感觉效率变高主要是由于循环次数的减少,不知道对不对。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP