双重性能比C

时间:2015-09-04 20:24:26

标签: c performance floating-point double x87

我试图弄清楚在C中的某些代码中使用浮点数是否足以满足我的需求,但是在搜索之后并没有真正理解精度位如何转换为实际数字时,我决定只写一些代码对于我的测试用例,看看结果如何。

Floats看起来足够精确,但我很惊讶浮标在我的17 4700hq haswell处理器(Windows 8.1 x64,C,MSVS v120)上运行时间延长了约70%。我原本期望运行时间相似或浮动表现更快。但显然不是。所以我关闭了所有的优化,仍然是相同的。在调试版本上尝试过它,但仍然存在相同的性能问题。 AVX2和SSE 3都显示了这一点。

双打需要大约197秒才能运行并且花费343秒。

我已经浏览了英特尔®64和IA-32架构软件开发人员手册,但考虑到它的规模和我缺乏专业知识,我还没有从中收集任何有关此问题的答案。然后我看了两个人的拆卸,但我没有注意到我未经训练的眼睛有任何明显的差异。

所以,有人知道为什么会这样吗?这是我使用的代码,除了anError变量之外,唯一的变化是从双精度到浮点数。

#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <omp.h>



int main( void ) {

    clock_t start = clock() ;

    // body of a candle
    double open = 0.500000 ;
    double close = 0.500001 ;
    double end = 1 ;

    uint64_t resultCounter = 0 ;
    double anError = 0 ;

    while (open < end){
        while(close < end){
            //calc # times result is postive. Should be 0.
            double res = open - close ;
            if (res > 0 ) { 
                resultCounter++ ; 
                if (anError < fabs( res )) { anError = res ;    }
            }
            close = close + 0.000001 ;
        }
        open = open + 0.000001 ;
        close = open + .000001 ;
    }

    clock_t finish = clock() ;
    double duration = ((double) (finish - start)) / CLOCKS_PER_SEC;
    double iterations = (((end - .50000) / .000001) * ((end - .50000) / .000001)) ;
    fprintf( stdout, "\nTotal processing time was %f seconds.\n", duration ) ;
    fprintf( stdout, "Error is %f. Number of times results were incorrect %llu out of %f iterations.\n", 
        anError, resultCounter, iterations ) ;

    return 0  ;
}
编辑:数字末尾缺少f似乎是原因(感谢Joachim!)。显然没有f后缀的浮点常数实际上是双倍的!另一个C的怪癖,喜欢咬屁股中的愚昧人。不确定这种奇怪背后的理由是什么,但耸肩。如果有人想为此写出一个好的答案,那么我可以接受它,请随意。

1 个答案:

答案 0 :(得分:0)

根据C标准:

  

未加浮动的常量类型为double。如果后缀是字母f或F,则浮动常量的类型为float。如果后缀是字母l或L,则浮动常量的类型为long double

有关浮点常数here的更多详细信息。所以:

num只是一个浮动

float num = 1.0f;
float num = 1.0F;

一个double被转换为float并存储在num

float num = 1.0;

一个float被转换为double并存储在num

double num = 1.0f;
double num = 1.0F;

由于常量从double转换为float而导致复制内存时使用浮点数时性能更差。