public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] GCD: add binary GCD algorithm
@ 2014-08-15 12:49 Zhaoxiu Zeng
  2014-08-15 13:58 ` Peter Zijlstra
  2014-08-22 21:31 ` Andrew Morton
  0 siblings, 2 replies; 8+ messages in thread
From: Zhaoxiu Zeng @ 2014-08-15 12:49 UTC (permalink / raw)
  To: Andrew Morton, Ingo Molnar, George Spelvin, David Howells,
	Peter Zijlstra, AKASHI Takahiro, Josh Boyer
  Cc: linux-kernel, Zhaoxiu Zeng

Because some architectures (alpha, armv6, etc.) don't provide hardware division,
the mod operation is slow! Binary GCD algorithm uses simple arithmetic operations,
it replaces division with arithmetic shifts, comparisons, and subtraction.

Signed-off-by: Zhaoxiu Zeng <zhaoxiu.zeng@gmail.com>
---
 lib/Kconfig | 15 +++++++++++++++
 lib/gcd.c   | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/lib/Kconfig b/lib/Kconfig
index a5ce0c7..80e8e54 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -177,6 +177,21 @@ config CRC8
 	  when they need to do cyclic redundancy check according CRC8
 	  algorithm. Module will be called crc8.
 
+#
+# GCD
+#
+choice
+	prompt "GCD implementation"
+	default GCD_ALGO_EUCLIDEAN
+
+config GCD_ALGO_EUCLIDEAN
+	bool "Euclidean algorithm"
+
+config GCD_ALGO_BINARY
+	bool "Binary GCD algorithm (Stein's algorithm)"
+
+endchoice
+
 config AUDIT_GENERIC
 	bool
 	depends on AUDIT && !AUDIT_ARCH
diff --git a/lib/gcd.c b/lib/gcd.c
index 3657f12..911ec7f 100644
--- a/lib/gcd.c
+++ b/lib/gcd.c
@@ -6,7 +6,7 @@
 unsigned long gcd(unsigned long a, unsigned long b)
 {
 	unsigned long r;
-
+#ifdef CONFIG_GCD_ALGO_EUCLIDEAN
 	if (a < b)
 		swap(a, b);
 
@@ -16,6 +16,35 @@ unsigned long gcd(unsigned long a, unsigned long b)
 		a = b;
 		b = r;
 	}
+#else
+	r = a | b;
+
+	if (!a || !b)
+		return r;
+
+	r = r ^ (r - 1);
+	if (!(a & r))
+		goto even_odd; /* a/c even, b/c odd */
+	if (!(b & r))
+		goto odd_even; /* a/c odd, b/c even */
+
+	/* a/c and b/c both odd */
+	while (a != b) {
+		if (a > b) {
+			a -= b;
+even_odd:
+			do
+				a >>= 1;
+			while (!(a & r));
+		} else {
+			b -= a;
+odd_even:
+			do
+				b >>= 1;
+			while (!(b & r));
+		}
+	}
+#endif
 	return b;
 }
 EXPORT_SYMBOL_GPL(gcd);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-08-22 22:36 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-15 12:49 [PATCH 1/1] GCD: add binary GCD algorithm Zhaoxiu Zeng
2014-08-15 13:58 ` Peter Zijlstra
2014-08-15 16:41   ` zhaoxiu.zeng
2014-08-15 21:53     ` George Spelvin
2014-08-15 20:16   ` George Spelvin
2014-08-15 21:32     ` Peter Zijlstra
2014-08-22 21:31 ` Andrew Morton
2014-08-22 22:36   ` George Spelvin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox