Skip to content

Commit

Permalink
Fix slowdown with 64 bit mul
Browse files Browse the repository at this point in the history
  • Loading branch information
mborland committed Feb 20, 2025
1 parent 3edf5fc commit 154d3b1
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 20 deletions.
6 changes: 4 additions & 2 deletions include/boost/decimal/decimal64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1429,8 +1429,10 @@ constexpr auto operator*(decimal64 lhs, decimal64 rhs) noexcept -> decimal64
}
#endif

const auto lhs_components {lhs.to_components()};
const auto rhs_components {rhs.to_components()};
auto lhs_components {lhs.to_components()};
detail::normalize(lhs_components.sig, lhs_components.exp);
auto rhs_components {rhs.to_components()};
detail::normalize(rhs_components.sig, rhs_components.exp);

return detail::d64_mul_impl<decimal64>(lhs_components, rhs_components);
}
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/decimal64_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ BOOST_DECIMAL_EXPORT class decimal64_fast final
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint64_t);

template <typename ReturnType, typename T>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto detail::d64_mul_impl(const T& lhs, const T& rhs) noexcept -> std::enable_if_t<detail::is_fast_type_v<ReturnType>, ReturnType>;
friend constexpr auto detail::d64_mul_impl(const T& lhs, const T& rhs) noexcept -> ReturnType;

template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;
Expand Down
18 changes: 1 addition & 17 deletions include/boost/decimal/detail/mul_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,9 @@ BOOST_DECIMAL_FORCE_INLINE constexpr auto mul_impl(T lhs_sig, U lhs_exp, bool lh
return {static_cast<std::uint32_t>(res_sig), res_exp, lhs_sign != rhs_sign};
}

template <typename ReturnType, typename T>
BOOST_DECIMAL_FORCE_INLINE constexpr auto d64_mul_impl(const T& lhs, const T& rhs) noexcept -> std::enable_if_t<detail::is_ieee_type_v<ReturnType>, ReturnType>
{
// Clang 6-12 yields incorrect results with builtin u128, so we force usage of our version
#if defined(BOOST_DECIMAL_HAS_INT128) && (!defined(__clang_major__) || (__clang_major__) > 12)
using unsigned_int128_type = boost::decimal::detail::uint128_t;
#else
using unsigned_int128_type = boost::decimal::detail::uint128;
#endif

const auto res_sig {(static_cast<unsigned_int128_type>(lhs.full_significand()) * static_cast<unsigned_int128_type>(rhs.full_significand()))};
const auto res_exp {lhs.biased_exponent() + rhs.biased_exponent()};

return {res_sig, res_exp, lhs.isneg() != rhs.isneg()};
}

// In the fast case we are better served doing our 128-bit division here since we are at a know starting point
template <typename ReturnType, typename T>
BOOST_DECIMAL_FORCE_INLINE constexpr auto d64_mul_impl(const T& lhs, const T& rhs) noexcept -> std::enable_if_t<detail::is_fast_type_v<ReturnType>, ReturnType>
constexpr auto d64_mul_impl(const T& lhs, const T& rhs) noexcept -> ReturnType
{
// Clang 6-12 yields incorrect results with builtin u128, so we force usage of our version
#if defined(BOOST_DECIMAL_HAS_INT128) && (!defined(__clang_major__) || (__clang_major__) > 12)
Expand Down

0 comments on commit 154d3b1

Please sign in to comment.