Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 长双精度(80位)的速度是双精度的两倍,具有安全的数学优化功能_C_Gcc_Floating Point_Compiler Optimization - Fatal编程技术网

C 长双精度(80位)的速度是双精度的两倍,具有安全的数学优化功能

C 长双精度(80位)的速度是双精度的两倍,具有安全的数学优化功能,c,gcc,floating-point,compiler-optimization,C,Gcc,Floating Point,Compiler Optimization,我一直认为,在使用-funsafe数学优化时,使用长双精度数据类型的计算速度大约是使用双精度的两倍。我想了解一下这一点,因为80位格式早就被弃用了,或者我可能正在用double数据类型做一些非常愚蠢的事情。编译器是g++4.8.2,目标是x86_64(因此,如果我不使用长双精度,gcc更喜欢SSE2) 我的代码大致如下(伪代码): //x是一个浮点数数组 对于i->x尺寸 累加器=0 对于k->kmax 累加器+=A[k]*(B[k]*cos(C*k*x[i])-D[k]*sin(C*k*x[i

我一直认为,在使用
-funsafe数学优化时,使用
长双精度
数据类型的计算速度大约是使用
双精度
的两倍。我想了解一下这一点,因为80位格式早就被弃用了,或者我可能正在用
double
数据类型做一些非常愚蠢的事情。编译器是g++4.8.2,目标是x86_64(因此,如果我不使用
长双精度
,gcc更喜欢SSE2)

我的代码大致如下(伪代码):

//x是一个浮点数数组
对于i->x尺寸
累加器=0
对于k->kmax
累加器+=A[k]*(B[k]*cos(C*k*x[i])-D[k]*sin(C*k*x[i]);
x[i]+=F*累加器;
如果(x[i]>=1/2)x[i]=integer(x[i]+1/2);
如果(x[i]<-1/2)x[i]=整数(x[i]-1/2);
A
B
。。是一些预计算的数组/常量

加速似乎与缓存线问题无关,因为如果我使用OpenMP并行化外部for循环,我会得到相同的相对加速

编辑:
我更正了伪代码:注意
cos
sin
有相同的参数,这就是最终加速的原因(请参见gsg的答案和注释)。

我猜差异是由于
cos
造成的

必须将
长双精度
数学编译成x87指令,从而使x87操作
fcos
的使用变得简单高效。但是,
xmm
寄存器没有超越操作,因此对cos的调用必须生成代码,将
double
移动到x87堆栈上并调用
fcos
,或者进行函数调用以执行等效工作。对于这个编译器和机器来说,这些可能更昂贵


您可以通过查看程序集(查找
callcos
或x87指令)来验证这一点,也可能值得使用
-mfpmath=387
进行编译,以查看性能特征是否发生变化。

if
for
语句的分支历史记录是否有任何变化?原因是什么两个版本的汇编程序输出?当使用
long double
时,您使用的是
cosl()
还是
cos()
?您的“80位格式从很长时间以来就被弃用”的来源是什么?@PatriciaShanahan我不确定我是否理解您的意思。我不使用任何基于配置文件的优化,并且if/elseif的平均使用次数也不会改变。请检查。你有没有解释过这只会发生在
-funsafe数学优化中?因为当x87 FCO“不安全”时,@LorenzoPistone,x87三角指令在某些型号的处理器上具有低于标准的参数缩减。请参见观察:gcc在历史上发出了对
cos
的调用,除非指定了
-ffast math
,在这种情况下,它使用
fcos
指令。这个决定可能是因为
cos(3)
应该为
NaN
参数设置
errno
,但我不确定。我在问题中输入了一个错误:我没有两个
cos
,而是一个
cos
和一个
sin
具有相同参数。我在汇编中看到这条指令,
fsincos
,我很确定这就是大幅加速的原因。没有
-funsafe数学优化
,我接到一个电话到
sincosl
@gsg,我接受了你的回答。如果你也提到这件事,那就太好了。其他操作,如
sqrt
似乎不受
-funsafe数学优化的影响。
//x is an array of floating point numbers
for i -> x.size
        accumulator = 0
        for k -> kmax
            accumulator += A[k]*(B[k]*cos(C*k*x[i]) - D[k]*sin(C*k*x[i]));
        x[i] += F*accumulator;
        if(x[i] >= 1/2) x[i] -= integer(x[i]+1/2);
        else if(x[i] < -1/2) x[i] -= integer(x[i]-1/2);