c - long double(80 位)是使用 -funsafe-math-optimizations 的两倍快

标签 c gcc floating-point compiler-optimization

在使用 -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, .. 是一些预先计算的数组/常量。

加速似乎与缓存行问题无关,因为如果我将外部 for 循环与 OpenMP 并行化,我将获得相同的相对加速。

编辑: 我更正了伪代码:注意 cossin 有相同的参数,这最终是加速的原因(参见 gsg 的回答和评论)。

最佳答案

我的猜测是,差异是由于 cos 造成的。

long double 数学运算必须编译成 x87 指令,这样可以轻松高效地使用 x87 操作 fcos。但是,xmm 寄存器没有超越操作,因此对 cos 的调用必须生成代码以将 double 移动到 x87 堆栈并调用 fcos,或者调用一个函数来做同样的工作。这些对于这个编译器和机器来说可能更昂贵。

您可以尝试通过查看程序集来验证这一点 - 寻找 call cos 或 x87 指令 - 也可能值得使用 -mfpmath=387 编译到查看性能特征是否发生变化。

关于c - long double(80 位)是使用 -funsafe-math-optimizations 的两倍快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20602599/

相关文章:

c - 如何将 char 数组转换为 float 并检查其范围?

c++ - float 到固定转换

c - 让 printf 使用浮点做正确的事情

c - 如何将值放入数组结构中?

c - 如何在 gcc/mingw 内联汇编中添加简单的 float4

c++ - 将 gcc 属性与 C++11 属性语法一起使用

c - 以错误的方式定义结构

c++ - 通过指针算法计算数组长度

c - 如何从C语言结构中读取值

c - ==符号是什么意思?