[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