stop compiler optimizations with -ffast-math from break sum accumulator

This commit is contained in:
Hans Dembinski 2019-12-20 20:13:39 +01:00 committed by GitHub
parent b3a8158878
commit 1305445ce4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 16 deletions

View File

@ -48,12 +48,21 @@ public:
/// Increment sum by value
sum& operator+=(const RealType& value) {
auto temp = large_ + value; // prevent optimization
if (std::abs(large_) >= std::abs(value))
small_ += (large_ - temp) + value;
else
small_ += (value - temp) + large_;
large_ = temp;
// prevent compiler optimization from destroying the algorithm
// when -ffast-math is enabled
volatile RealType l;
RealType s;
if (std::abs(large_) >= std::abs(value)) {
l = large_;
s = value;
} else {
l = value;
s = large_;
}
large_ += value;
l -= large_;
l += s;
small_ += l;
return *this;
}

View File

@ -16,9 +16,12 @@ namespace histogram {
namespace accumulators {
/// Holds sum of weights and its variance estimate
template <typename RealType>
template <class RealType>
class weighted_sum {
public:
using value_type = RealType;
using const_reference = const RealType&;
weighted_sum() = default;
explicit weighted_sum(const RealType& value) noexcept
: sum_of_weights_(value), sum_of_weights_squared_(value) {}
@ -67,16 +70,13 @@ public:
}
/// Return value of the sum.
const RealType& value() const noexcept { return sum_of_weights_; }
const_reference value() const noexcept { return sum_of_weights_; }
/// Return estimated variance of the sum.
const RealType& variance() const noexcept { return sum_of_weights_squared_; }
const_reference variance() const noexcept { return sum_of_weights_squared_; }
// lossy conversion must be explicit
template <class T>
explicit operator T() const {
return static_cast<T>(sum_of_weights_);
}
explicit operator const_reference() const { return sum_of_weights_; }
template <class Archive>
void serialize(Archive& ar, unsigned /* version */) {
@ -85,8 +85,8 @@ public:
}
private:
RealType sum_of_weights_ = RealType();
RealType sum_of_weights_squared_ = RealType();
value_type sum_of_weights_ = value_type();
value_type sum_of_weights_squared_ = value_type();
};
} // namespace accumulators

View File

@ -38,7 +38,10 @@ alias odr :
;
alias cxx14 :
[ run accumulators_test.cpp ]
[ run accumulators_test.cpp : : :
# make sure sum accumulator works even with -ffast-math and optimizations
<toolset>gcc:<cxxflags>"-O3 -ffast-math"
<toolset>clang:<cxxflags>"-O3 -ffast-math" ]
[ run algorithm_project_test.cpp ]
[ run algorithm_reduce_test.cpp ]
[ run algorithm_sum_test.cpp ]