Skip to content

Commit

Permalink
Optimize less-than
Browse files Browse the repository at this point in the history
The new implementation is similar to what was there: we select which
half to compare and do 128-bit less-than. For small values this is
equivalent to do subtraction + borrow check, for big values though we
get 25% boost.
  • Loading branch information
chfast committed Mar 15, 2022
1 parent ce3f7a1 commit f4cff75
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
13 changes: 8 additions & 5 deletions include/intx/intx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1087,11 +1087,14 @@ inline constexpr bool operator!=(const T& x, const uint<N>& y) noexcept
#if !defined(_MSC_VER) || _MSC_VER < 1916 // This kills MSVC 2017 compiler.
inline constexpr bool operator<(const uint256& x, const uint256& y) noexcept
{
const auto xhi = uint128{x[2], x[3]};
const auto xlo = uint128{x[0], x[1]};
const auto yhi = uint128{y[2], y[3]};
const auto ylo = uint128{y[0], y[1]};
return (unsigned(xhi < yhi) | (unsigned(xhi == yhi) & unsigned(xlo < ylo))) != 0;
auto xp = intx::uint128{x[2], x[3]};
auto yp = intx::uint128{y[2], y[3]};
if (xp == yp)
{
xp = intx::uint128{x[0], x[1]};
yp = intx::uint128{y[0], y[1]};
}
return xp < yp;
}
#endif

Expand Down
6 changes: 6 additions & 0 deletions test/benchmarks/benchmarks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ BENCHMARK_TEMPLATE(shift, uint512, uint64_t, shl_public)->DenseRange(-1, 3);
return x < y;
}

[[gnu::noinline]] static bool lt_sub(const uint256& x, const uint256& y) noexcept
{
return subc(x, y).carry;
}

[[gnu::noinline]] static bool lt_wordcmp(const uint256& x, const uint256& y) noexcept
{
for (size_t i = 3; i >= 1; --i)
Expand Down Expand Up @@ -418,6 +423,7 @@ static void compare(benchmark::State& state)
}
}
BENCHMARK_TEMPLATE(compare, lt_public)->DenseRange(64, 256, 64);
BENCHMARK_TEMPLATE(compare, lt_sub)->DenseRange(64, 256, 64);
BENCHMARK_TEMPLATE(compare, lt_wordcmp)->DenseRange(64, 256, 64);
BENCHMARK_TEMPLATE(compare, lt_halves)->DenseRange(64, 256, 64);
#if INTX_HAS_EXTINT
Expand Down

0 comments on commit f4cff75

Please sign in to comment.