由GCC编译的Kahan求和算法存在较大的计算误差

我使用Kahan求和算法:

inline void KahanSum(float value, float & sum, float & correction)

{

float term = value - correction;

float temp = sum + term;

correction = (temp - sum) - term;

sum = temp;

}

float KahanSum(const float * ptr, size_t size)

{

float sum = 0, correction = 0;

for(size_t i = 0; i < size; ++i)

KahanSum(ptr[i], sum, correction);

return sum;

}

如果使用MSVS进行编译,它可以正常工作,但是当我使用GCC时,它存在很大的计算错误。

麻烦在哪里?

回答:

我支持,这是激进的编译器优化的结果。因此,GCC可以减少以下表达式:

    float term = value - correction;

float temp = sum + term;

correction = (temp - sum) - term;

sum = temp;

    float term = value - correction;

correction = 0;

sum += term;

因为这种转换在数学上是正确的,但是这种优化杀死了Kahan算法。

为了避免此问题,您可以使用“ -O1” GCC编译器选项来编译代码。将会是这样的:

#if defined(__GNUC__)

# pragma GCC push_options

# pragma GCC optimize ("O1")

#endif

inline void KahanSum(float value, float & sum, float & correction)

{

float term = value - correction;

float temp = sum + term;

correction = (temp - sum) - term;

sum = temp;

}

float KahanSum(const float * ptr, size_t size)

{

float sum = 0, correction = 0;

for(size_t i = 0; i < size; ++i)

KahanSum(ptr[i], sum, correction);

return sum;

}

#if defined(__GNUC__)

# pragma GCC pop_options

#endif

以上是 由GCC编译的Kahan求和算法存在较大的计算误差 的全部内容, 来源链接: utcz.com/qa/407072.html

回到顶部