mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 23:04:07 +00:00
stop compiler optimizations with -ffast-math from break sum accumulator
This commit is contained in:
parent
b3a8158878
commit
1305445ce4
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 ]
|
||||
|
Loading…
x
Reference in New Issue
Block a user