SSE与串行浮点加法不匹配

时间:2011-05-02 08:31:30

标签: vector comparison precision sse

这是给我悲伤的测试程序:

#include <xmmintrin.h>
#include <stdio.h>

inline float
_mm_hadd_ps(const __m128 v)
{
    const __m128
        x = _mm_add_ps(v, _mm_movehl_ps(v, v)),
        xx = _mm_add_ss(x, _mm_shuffle_ps(x, x, 1));

    float __attribute__((aligned(16))) s;
    _mm_store_ss(&s, xx);
    return s;
}


int
main(void)
{
    const float __attribute__((aligned(16))) d[] = { 
        4.0763611794e+00, 1.1881252751e-02, 4.9195003510e+00, 0.0000000000e+00
    };  

    const float x = _mm_hadd_ps(_mm_load_ps(d));
    const float y = d[0] + d[1] + d[2] + d[3];

    printf("diff: %.10f\n", x - y); 
    return 0;
}

我正在使用以下内容进行编译:

gcc -Wall -msse2 -mfpmath=sse -O0 -g -ggdb sse.c

我得到的输出是:

diff: -0.0000009537

我知道扩展精度算术的问题,因此mfpmath=sse。查看汇编代码,序列添加确实使用addss完成,最后减法使用subss

此时我很难解释这种差异来自哪里。如果有人能说清楚这种情况,我会非常感激。

如果它有任何区别,我正在使用GCC 4.3.4。 (编辑:在AMD Opteron 2218 + Gentoo Linux上)

1 个答案:

答案 0 :(得分:1)

FWIW gcc 4.2和Intel ICC 11.1都给出了完全相同的结果。我怀疑由于执行添加的顺序不同,累积的舍入误差只是差异。