From: Paul Eggert Date: Thu, 9 Jul 2020 01:58:18 +0000 (-0700) Subject: factor: explain why non-GMP code (Bug#42269) X-Git-Tag: v9.0~217 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55d985064c5a39ea2a6695570562a91044abe699;p=thirdparty%2Fcoreutils.git factor: explain why non-GMP code (Bug#42269) * doc/coreutils.texi (factor invocation): * src/factor.c: Explain why the two-word algorithm is useful. --- diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 6ec1e6c314..656b8bc791 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -18368,14 +18368,17 @@ Print the program version on standard output, then exit without further processing. @end table -Factoring the product of the eighth and ninth Mersenne primes -takes about 4 milliseconds of CPU time on an Intel Xeon Silver 4116. +If the number to be factored is small (less than @math{2^{127}} on +typical machines), @command{factor} uses a faster algorithm. +For example, on a circa-2017 Intel Xeon Silver 4116, factoring the +product of the eighth and ninth Mersenne primes (approximately +@math{2^{92}}) takes about 4 ms of CPU time: @example -M8=$(echo 2^31-1|bc) -M9=$(echo 2^61-1|bc) -n=$(echo "$M8 * $M9" | bc) -bash -c "time factor $n" +$ M8=$(echo 2^31-1 | bc) +$ M9=$(echo 2^61-1 | bc) +$ n=$(echo "$M8 * $M9" | bc) +$ bash -c "time factor $n" 4951760154835678088235319297: 2147483647 2305843009213693951 real 0m0.004s @@ -18383,11 +18386,12 @@ user 0m0.004s sys 0m0.000s @end example -Similarly, factoring the eighth Fermat number @math{2^{256}+1} takes -about 14 seconds on the same machine. +For larger numbers, @command{factor} uses a slower algorithm. On the +same platform, factoring the eighth Fermat number @math{2^{256} + 1} +takes about 14 seconds, and the slower algorithm would have taken +about 750 ms to factor @math{2^{127} - 3} instead of the 50 ms needed by +the faster algorithm. -The single-precision code uses an algorithm -designed for factoring smaller numbers. Factoring large numbers is, in general, hard. The Pollard-Brent rho algorithm used by @command{factor} is particularly effective for numbers with relatively small factors. If you wish to factor large diff --git a/src/factor.c b/src/factor.c index c1c35a5629..1b1607f165 100644 --- a/src/factor.c +++ b/src/factor.c @@ -53,6 +53,11 @@ trick of multiplying all n-residues by the word base, allowing cheap Hensel reductions mod n. + The GMP code uses an algorithm that can be considerably slower; + for example, on a circa-2017 Intel Xeon Silver 4116, factoring + 2^{127}-3 takes about 50 ms with the two-word algorithm but would + take about 750 ms with the GMP code. + Improvements: * Use modular inverses also for exact division in the Lucas code, and