首頁  >  問答  >  主體

效率 - c++中float的计算速度比double慢?

c++中float的计算速度比double慢

 浮点运算都是以双精度进行的,即使只有float的运算,也要先转换成double型再计算。
  所以doublex型比float型要快一点。
  C++ 标准要求 float 类型至少要能精确表示到小数点后6位,并且整数部分的表示范围至少要达到 1.0-37 -- 10+37 。float 一般是 32 位的。
  C ++标准规定double 类型的整数部分的最小表示范围和 float 一样,都是 1.0E-37 到 1.0E+37,但是它要求 double 类型的小数部分至少要能精确到小数点后 10 位。double 通常是 64 位的。

VC编译的时候float会转double,建议以后直接用double做浮点数运算,这样既能保证精度有能提高速度。


这是在网上找到的一段回答。 但在没有指定编译环境和语言时,很多网上的帖子都直接说float比较快。 所以现在我乱了。
巴扎黑巴扎黑2718 天前1048

全部回覆(2)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:08:16

    VC++來說,一般分為兩種情況。

    第一種情況是你編譯32位元程式的時候,它會使用X87指令集。在現代的cpu裡面,X87內部有一個小堆疊,每個元素都是80位元或128位元的浮點。不管你用的是float、double,還是其他的類型,反正push進去了都會normalize成一樣長的80位或者128位的浮點,全部算完了再給你轉回來。所以速度應該是幾乎一致的。

    第二種情況是你編譯64位元程序,或是開啟了MMX、SSE、AVX指令集最佳化,或是你乾脆就是用intrinsic來直接使用這些指令集。這些指令目前支援float和double,而且不會跟X87一樣統一轉格式。 double不僅資料是float的兩倍,而且同樣大小的暫存器可以同時存放的double數量要比float數量少一半,因此並行之後,float就會比double快很多。

    當然了,在很多情況下,float的精度實際上是不夠的,而且使用intrinsic的時候,你自己的水平的影響比double的影響要大幾個數量級,所以看你的需要了,以需求為主。

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-17 13:08:16

    是double快點的。
    我寫了一個測試程式碼`main()
    {
    //float f1=0.0;
    double f1=0.0;
    int i,j;
    for(i= 0;i<100000;i++){
    for(j=0;j<10000;j++)f1+=1.1;
    f1-=11000;
    }
    printf("%fn", f1);
    }
    `
    float:
    root@i5a:~/test# time ./a.out
    -1412.595703

    real 0m3.063s
    user 0m3.065s
    sys 0m0.000s

    doubule
    time ./a.out
    0.000204

    real 0m0.843s
    user 0m0.840s
    sys 0m0.004s

    相差近4倍
    來看看gcc -c -S,只看循環體部分
    double:

    .L2:
            movl    000, %eax
            .p2align 4,,10
            .p2align 3
    .L5:
            subl    , %eax
            addsd   %xmm1, %xmm0
            jne     .L5
            subl    , %edx
            subsd   %xmm2, %xmm0
            jne     .L2
            

    再來看看float:

     .L2:
            movl    000, %eax
            .p2align 4,,10
            .p2align 3
    .L5:
            unpcklps        %xmm0, %xmm0
            subl    , %eax
            cvtps2pd        %xmm0, %xmm0
            addsd   %xmm1, %xmm0
            unpcklpd        %xmm0, %xmm0
            cvtpd2ps        %xmm0, %xmm0
            jne     .L5
            subl    , %edx
            subss   %xmm2, %xmm0
            jne     .L2
            unpcklps        %xmm0, %xmm0
            movl    $.LC3, %edi
            movl    , %eax
            cvtps2pd        %xmm0, %xmm0
            jmp     printf
            
            

    都已經開啟了-O2最佳化。

    再來看看編譯成32位元的情況。
    double:
    .L8:

        fxch    %st(1)

    .L2:

        movl    000, %eax
        .p2align 4,,7
        .p2align 3

    .L5:

        subl    , %eax
        fadd    %st, %st(1)
        jne     .L5
        fxch    %st(1)
        subl    , %edx
        fsubs   .LC2
        jne     .L8
    

    float:
    .L9:

        fxch    %st(1)

    .L2:

        movl    000, %eax
        jmp     .L5
        .p2align 4,,7
        .p2align 3

    .L8:

        fxch    %st(1)

    .L5:

        fadd    %st, %st(1)
        fxch    %st(1)
        subl    , %eax
        fstps   12(%esp)
        flds    12(%esp)
        jne     .L8
        subl    , %edx
        fsubs   .LC2
        jne     .L9

    測試結果double跟64位差不多,0.85秒,float2.78秒,比64位的float快一點點。

    回覆
    0
  • 取消回覆