我一致认为使用long double
数据类型的速度大约是使用double
时使用-funsafe-math-optimizations
进行计算的速度的两倍。我想对此有所了解,因为80位格式不久就被弃用了,或者我可能会使用double
数据类型做一些非常愚蠢的事情。编译器是g ++ 4.8.2,目标是x86_64(如果我不使用long double
,gcc会更喜欢SSE2。)
我的代码或多或少像这样(伪代码):
//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);
A
,B
,..是一些预先计算的数组/常量。
加速似乎与高速缓存行问题无关,因为如果我使用OpenMP并行化外部for循环,我会获得相同的相对加速。
编辑:
我更正了伪代码:注意cos
和sin
具有相同的参数,这最终是加速的原因(请参阅gsg的答案和注释)。
答案 0 :(得分:2)
我的猜测是差异是由于cos
。
必须将long double
数学编译成x87指令,这样可以轻松高效地使用x87操作fcos
。但是xmm
寄存器没有超越操作,因此对cos的调用必须生成代码以将double
移动到x87堆栈并调用fcos
,或者调用函数调用做同等的工作。据推测,这些编译器和机器的成本更高。
您可以尝试通过查看程序集来查看此问题 - 查找call cos
或x87指令 - 也可能值得使用-mfpmath=387
进行编译,以查看性能特征是否发生变化。