From 3d990e8b023f6125a8de19ea80c64aa659af8d9b Mon Sep 17 00:00:00 2001 From: KRM7 <70973547+KRM7@users.noreply.github.com> Date: Sun, 24 Sep 2023 18:32:39 +0200 Subject: [PATCH] update floating point context docs Also make the tolerance values non-atomic, since there is no real benefit anyway. --- docs/miscellaneous.md | 5 +++++ src/utility/math.hpp | 30 ++++++++++++++++-------------- test/unit/pareto_sets.cpp | 1 - 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/docs/miscellaneous.md b/docs/miscellaneous.md index b6cf83a1..95e44788 100644 --- a/docs/miscellaneous.md +++ b/docs/miscellaneous.md @@ -48,6 +48,11 @@ Exact comparisons can be used by setting both tolerance values to 0. math::ScopedTolerances _(0.0, 0.0); ``` +Note that the tolerance values are global variables which will be used for +the comparisons on every thread, so they should not be modified on multiple +threads concurrently. This means that instances of the `ScopedTolerances` +class should not exist on multiple threads at once. + ## Random number generation diff --git a/src/utility/math.hpp b/src/utility/math.hpp index fa41595e..8df46355 100644 --- a/src/utility/math.hpp +++ b/src/utility/math.hpp @@ -3,10 +3,10 @@ #ifndef GA_UTILITY_MATH_HPP #define GA_UTILITY_MATH_HPP +#include "bounded_value.hpp" #include "utility.hpp" #include #include -#include #include #include #include @@ -44,15 +44,15 @@ namespace gapp::math /** @returns The current absolute tolerance used for floating-point comparisons. */ template - static T abs() noexcept { return T(absolute_tolerance.load(std::memory_order_acquire)); } + static T abs() noexcept { return T(absolute_tolerance); } /** @returns The current relative tolerance used for floating-point comparisons around @p at. */ template - static T rel(T at) noexcept { return relative_tolerance.load(std::memory_order_acquire) * at; } + static T rel(T at) noexcept { return relative_tolerance * at; } private: - GAPP_API inline constinit static std::atomic absolute_tolerance = 1E-12; - GAPP_API inline constinit static std::atomic relative_tolerance = 10 * eps; + GAPP_API inline constinit static double absolute_tolerance = 1E-12; + GAPP_API inline constinit static double relative_tolerance = 10 * eps; friend class ScopedTolerances; }; @@ -65,6 +65,11 @@ namespace gapp::math * values specified by the parameters of the constructor, and these new tolerance * values will be used for floating-point comparisons until the instance of the class is destroyed. * The tolerances are reset to their old values when the instance is destroyed. + * + * @warning + * Creating an instance of this class modifies the global floating point tolerance + * values. This means that this class shouldn't be instantiated on multiple threads + * at once. */ class [[nodiscard]] ScopedTolerances { @@ -76,19 +81,16 @@ namespace gapp::math * @param abs The absolute tolerance value that will be used for the comparisons. Can't be negative. * @param rel The relative tolerance value around 1.0 that will be used for the comparisons. Can't be negative. */ - ScopedTolerances(double abs, double rel) noexcept : - old_absolute_tolerance(Tolerances::absolute_tolerance.exchange(abs, std::memory_order_acq_rel)), - old_relative_tolerance(Tolerances::relative_tolerance.exchange(rel, std::memory_order_acq_rel)) - { - GAPP_ASSERT(abs >= 0.0, "The absolute tolerance value can't be negative."); - GAPP_ASSERT(rel >= 0.0, "The relative tolerance value can't be negative."); - } + ScopedTolerances(NonNegative abs, NonNegative rel) noexcept : + old_absolute_tolerance(std::exchange(Tolerances::absolute_tolerance, abs)), + old_relative_tolerance(std::exchange(Tolerances::relative_tolerance, rel)) + {} /** Reset the tolerances to their previous values. */ ~ScopedTolerances() noexcept { - Tolerances::absolute_tolerance.store(old_absolute_tolerance, std::memory_order_release); - Tolerances::relative_tolerance.store(old_relative_tolerance, std::memory_order_release); + Tolerances::absolute_tolerance = old_absolute_tolerance; + Tolerances::relative_tolerance = old_relative_tolerance; } ScopedTolerances(const ScopedTolerances&) = delete; diff --git a/test/unit/pareto_sets.cpp b/test/unit/pareto_sets.cpp index 031c406f..d6a9c1db 100644 --- a/test/unit/pareto_sets.cpp +++ b/test/unit/pareto_sets.cpp @@ -39,7 +39,6 @@ TEST_CASE("merge_pareto_sets", "[pareto_front]") { 3.0, 8.0 }, // { 2.0, 11.0 }, // { 1.0, 12.0 }, // - { -1.0, 10.0 }, }; FitnessMatrix front2 = {