Skip to content

Commit 6da3f5c

Browse files
committed
Force inlining, use ctz to reduce dependency in loop.
1 parent 600fed7 commit 6da3f5c

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

lib/std/math/egcd.zig

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn ExtendedGreatestCommonDivisor(S: anytype) type {
1515
};
1616
}
1717

18-
fn egcd_helper(other: anytype, odd: anytype, shift: anytype) [3]@TypeOf(other, odd) {
18+
inline fn egcd_helper(other: anytype, odd: anytype, shift: anytype) [3]@TypeOf(other, odd) {
1919
const S = @TypeOf(other, odd);
2020
const toinv = @shrExact(other, @intCast(shift));
2121
const ctrl = @shrExact(odd, @intCast(shift));
@@ -26,16 +26,19 @@ fn egcd_helper(other: anytype, odd: anytype, shift: anytype) [3]@TypeOf(other, o
2626
var x = @abs(toinv);
2727
var y = @abs(ctrl);
2828

29-
while (x & 1 == 0) {
30-
x = @shrExact(x, 1);
31-
s = @shrExact(if (s & 1 == 0) s else s + ctrl, 1);
29+
{
30+
const xz = @ctz(x);
31+
x = @shrExact(x, @intCast(xz));
32+
for (0..xz) |_|
33+
s = @shrExact(if (s & 1 == 0) s else s + ctrl, 1);
3234
}
3335

3436
var y_minus_x = y -% x;
3537
while (y_minus_x != 0) : (y_minus_x = y -% x) {
3638
const t_minus_s = t - s;
3739
const copy_x = x;
3840
const copy_s = s;
41+
const xz = @ctz(y_minus_x);
3942

4043
s -= t;
4144
const carry = x < y;
@@ -46,10 +49,9 @@ fn egcd_helper(other: anytype, odd: anytype, shift: anytype) [3]@TypeOf(other, o
4649
s = t_minus_s;
4750
t = copy_s;
4851
}
49-
while (x & 1 == 0) {
50-
x = @shrExact(x, 1);
52+
x = @shrExact(x, @intCast(xz));
53+
for (0..xz) |_|
5154
s = @shrExact(if (s & 1 == 0) s else s + ctrl, 1);
52-
}
5355
}
5456

5557
y = @shlExact(y, @intCast(shift));
@@ -83,13 +85,12 @@ pub fn egcd(a: anytype, b: anytype) ExtendedGreatestCommonDivisor(@TypeOf(a, b))
8385

8486
const xz = @ctz(x);
8587
const yz = @ctz(y);
86-
const shift = @min(xz, yz);
8788

8889
if (xz < yz) {
89-
const gcd, const t, const s = egcd_helper(y, x, shift);
90+
const gcd, const t, const s = egcd_helper(y, x, xz);
9091
return .{ .gcd = @intCast(gcd), .bezout_coeff_1 = s, .bezout_coeff_2 = t };
9192
} else {
92-
const gcd, const s, const t = egcd_helper(x, y, shift);
93+
const gcd, const s, const t = egcd_helper(x, y, yz);
9394
return .{ .gcd = @intCast(gcd), .bezout_coeff_1 = s, .bezout_coeff_2 = t };
9495
}
9596
}

0 commit comments

Comments
 (0)