[libcxx-commits] [libcxx] [libc++] Implement std::gcd using the binary version (PR #77747)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Apr 24 00:39:22 PDT 2024


ylchapuy wrote:

An hybrid approach with one modulo at the begining followed by the binary gcd loop could get us the best of both world I think.

Here a proposed implementation:
```
template <class T>
T binary_gcd(T u, T v) {
  if (u < v) std::swap(u, v);
  if (v == 0)
    return u;
  u %= v; // make both argument of the same size, and early result in the easy case
  if (u == 0)
    return v;

  auto zu = std::countr_zero(u);
  auto zv = std::countr_zero(v);
  auto shift = std::min(zu, zv);
  u >>= zu;
  v >>= zv;
  do {
    T u_minus_v = u - v;
    if (u > v)
      u = v, v = u_minus_v;
    else
      v = v - u;
    // v >>= std::countr_zero(v); !!! avoid instruction dependency
    v >>= std::countr_zero(u_minus_v);
  } while(v != 0);
  return u << shift;
}
```
And here some benchmarks: https://quick-bench.com/q/AMjI0bBfq3YCyz6XBtvINUNQsBs


https://github.com/llvm/llvm-project/pull/77747


More information about the libcxx-commits mailing list