You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
12 KiB
HTML
254 lines
12 KiB
HTML
4 years ago
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<!-- This manual describes how to install and use the GNU multiple precision
|
||
|
arithmetic library, version 6.1.0.
|
||
|
|
||
|
Copyright 1991, 1993-2015 Free Software Foundation, Inc.
|
||
|
|
||
|
Permission is granted to copy, distribute and/or modify this document under
|
||
|
the terms of the GNU Free Documentation License, Version 1.3 or any later
|
||
|
version published by the Free Software Foundation; with no Invariant Sections,
|
||
|
with the Front-Cover Texts being "A GNU Manual", and with the Back-Cover
|
||
|
Texts being "You have freedom to copy and modify this GNU Manual, like GNU
|
||
|
software". A copy of the license is included in
|
||
|
GNU Free Documentation License. -->
|
||
|
<!-- Created by GNU Texinfo 6.4, http://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<title>Efficiency (GNU MP 6.1.0)</title>
|
||
|
|
||
|
<meta name="description" content="How to install and use the GNU multiple precision arithmetic library, version 6.1.0.">
|
||
|
<meta name="keywords" content="Efficiency (GNU MP 6.1.0)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content="makeinfo">
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||
|
<link href="index.html#Top" rel="start" title="Top">
|
||
|
<link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
|
||
|
<link href="GMP-Basics.html#GMP-Basics" rel="up" title="GMP Basics">
|
||
|
<link href="Debugging.html#Debugging" rel="next" title="Debugging">
|
||
|
<link href="Demonstration-Programs.html#Demonstration-Programs" rel="prev" title="Demonstration Programs">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
a.summary-letter {text-decoration: none}
|
||
|
blockquote.indentedblock {margin-right: 0em}
|
||
|
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
|
||
|
blockquote.smallquotation {font-size: smaller}
|
||
|
div.display {margin-left: 3.2em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
div.lisp {margin-left: 3.2em}
|
||
|
div.smalldisplay {margin-left: 3.2em}
|
||
|
div.smallexample {margin-left: 3.2em}
|
||
|
div.smalllisp {margin-left: 3.2em}
|
||
|
kbd {font-style: oblique}
|
||
|
pre.display {font-family: inherit}
|
||
|
pre.format {font-family: inherit}
|
||
|
pre.menu-comment {font-family: serif}
|
||
|
pre.menu-preformatted {font-family: serif}
|
||
|
pre.smalldisplay {font-family: inherit; font-size: smaller}
|
||
|
pre.smallexample {font-size: smaller}
|
||
|
pre.smallformat {font-family: inherit; font-size: smaller}
|
||
|
pre.smalllisp {font-size: smaller}
|
||
|
span.nolinebreak {white-space: nowrap}
|
||
|
span.roman {font-family: initial; font-weight: normal}
|
||
|
span.sansserif {font-family: sans-serif; font-weight: normal}
|
||
|
ul.no-bullet {list-style: none}
|
||
|
-->
|
||
|
</style>
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<a name="Efficiency"></a>
|
||
|
<div class="header">
|
||
|
<p>
|
||
|
Next: <a href="Debugging.html#Debugging" accesskey="n" rel="next">Debugging</a>, Previous: <a href="Demonstration-Programs.html#Demonstration-Programs" accesskey="p" rel="prev">Demonstration Programs</a>, Up: <a href="GMP-Basics.html#GMP-Basics" accesskey="u" rel="up">GMP Basics</a> [<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<a name="Efficiency-1"></a>
|
||
|
<h3 class="section">3.11 Efficiency</h3>
|
||
|
<a name="index-Efficiency"></a>
|
||
|
|
||
|
<dl compact="compact">
|
||
|
<dt>Small Operands</dt>
|
||
|
<dd><a name="index-Small-operands"></a>
|
||
|
<p>On small operands, the time for function call overheads and memory allocation
|
||
|
can be significant in comparison to actual calculation. This is unavoidable
|
||
|
in a general purpose variable precision library, although GMP attempts to be
|
||
|
as efficient as it can on both large and small operands.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Static Linking</dt>
|
||
|
<dd><a name="index-Static-linking"></a>
|
||
|
<p>On some CPUs, in particular the x86s, the static <samp>libgmp.a</samp> should be
|
||
|
used for maximum speed, since the PIC code in the shared <samp>libgmp.so</samp> will
|
||
|
have a small overhead on each function call and global data address. For many
|
||
|
programs this will be insignificant, but for long calculations there’s a gain
|
||
|
to be had.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Initializing and Clearing</dt>
|
||
|
<dd><a name="index-Initializing-and-clearing"></a>
|
||
|
<p>Avoid excessive initializing and clearing of variables, since this can be
|
||
|
quite time consuming, especially in comparison to otherwise fast operations
|
||
|
like addition.
|
||
|
</p>
|
||
|
<p>A language interpreter might want to keep a free list or stack of
|
||
|
initialized variables ready for use. It should be possible to integrate
|
||
|
something like that with a garbage collector too.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Reallocations</dt>
|
||
|
<dd><a name="index-Reallocations"></a>
|
||
|
<p>An <code>mpz_t</code> or <code>mpq_t</code> variable used to hold successively increasing
|
||
|
values will have its memory repeatedly <code>realloc</code>ed, which could be quite
|
||
|
slow or could fragment memory, depending on the C library. If an application
|
||
|
can estimate the final size then <code>mpz_init2</code> or <code>mpz_realloc2</code> can
|
||
|
be called to allocate the necessary space from the beginning
|
||
|
(see <a href="Initializing-Integers.html#Initializing-Integers">Initializing Integers</a>).
|
||
|
</p>
|
||
|
<p>It doesn’t matter if a size set with <code>mpz_init2</code> or <code>mpz_realloc2</code>
|
||
|
is too small, since all functions will do a further reallocation if necessary.
|
||
|
Badly overestimating memory required will waste space though.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt><code>2exp</code> Functions</dt>
|
||
|
<dd><a name="index-2exp-functions"></a>
|
||
|
<p>It’s up to an application to call functions like <code>mpz_mul_2exp</code> when
|
||
|
appropriate. General purpose functions like <code>mpz_mul</code> make no attempt to
|
||
|
identify powers of two or other special forms, because such inputs will
|
||
|
usually be very rare and testing every time would be wasteful.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt><code>ui</code> and <code>si</code> Functions</dt>
|
||
|
<dd><a name="index-ui-and-si-functions"></a>
|
||
|
<p>The <code>ui</code> functions and the small number of <code>si</code> functions exist for
|
||
|
convenience and should be used where applicable. But if for example an
|
||
|
<code>mpz_t</code> contains a value that fits in an <code>unsigned long</code> there’s no
|
||
|
need extract it and call a <code>ui</code> function, just use the regular <code>mpz</code>
|
||
|
function.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>In-Place Operations</dt>
|
||
|
<dd><a name="index-In_002dplace-operations"></a>
|
||
|
<p><code>mpz_abs</code>, <code>mpq_abs</code>, <code>mpf_abs</code>, <code>mpz_neg</code>, <code>mpq_neg</code>
|
||
|
and <code>mpf_neg</code> are fast when used for in-place operations like
|
||
|
<code>mpz_abs(x,x)</code>, since in the current implementation only a single field
|
||
|
of <code>x</code> needs changing. On suitable compilers (GCC for instance) this is
|
||
|
inlined too.
|
||
|
</p>
|
||
|
<p><code>mpz_add_ui</code>, <code>mpz_sub_ui</code>, <code>mpf_add_ui</code> and <code>mpf_sub_ui</code>
|
||
|
benefit from an in-place operation like <code>mpz_add_ui(x,x,y)</code>, since
|
||
|
usually only one or two limbs of <code>x</code> will need to be changed. The same
|
||
|
applies to the full precision <code>mpz_add</code> etc if <code>y</code> is small. If
|
||
|
<code>y</code> is big then cache locality may be helped, but that’s all.
|
||
|
</p>
|
||
|
<p><code>mpz_mul</code> is currently the opposite, a separate destination is slightly
|
||
|
better. A call like <code>mpz_mul(x,x,y)</code> will, unless <code>y</code> is only one
|
||
|
limb, make a temporary copy of <code>x</code> before forming the result. Normally
|
||
|
that copying will only be a tiny fraction of the time for the multiply, so
|
||
|
this is not a particularly important consideration.
|
||
|
</p>
|
||
|
<p><code>mpz_set</code>, <code>mpq_set</code>, <code>mpq_set_num</code>, <code>mpf_set</code>, etc, make
|
||
|
no attempt to recognise a copy of something to itself, so a call like
|
||
|
<code>mpz_set(x,x)</code> will be wasteful. Naturally that would never be written
|
||
|
deliberately, but if it might arise from two pointers to the same object then
|
||
|
a test to avoid it might be desirable.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">if (x != y)
|
||
|
mpz_set (x, y);
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Note that it’s never worth introducing extra <code>mpz_set</code> calls just to get
|
||
|
in-place operations. If a result should go to a particular variable then just
|
||
|
direct it there and let GMP take care of data movement.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Divisibility Testing (Small Integers)</dt>
|
||
|
<dd><a name="index-Divisibility-testing"></a>
|
||
|
<p><code>mpz_divisible_ui_p</code> and <code>mpz_congruent_ui_p</code> are the best functions
|
||
|
for testing whether an <code>mpz_t</code> is divisible by an individual small
|
||
|
integer. They use an algorithm which is faster than <code>mpz_tdiv_ui</code>, but
|
||
|
which gives no useful information about the actual remainder, only whether
|
||
|
it’s zero (or a particular value).
|
||
|
</p>
|
||
|
<p>However when testing divisibility by several small integers, it’s best to take
|
||
|
a remainder modulo their product, to save multi-precision operations. For
|
||
|
instance to test whether a number is divisible by any of 23, 29 or 31 take a
|
||
|
remainder modulo <em>23*29*31 = 20677</em> and then test that.
|
||
|
</p>
|
||
|
<p>The division functions like <code>mpz_tdiv_q_ui</code> which give a quotient as well
|
||
|
as a remainder are generally a little slower than the remainder-only functions
|
||
|
like <code>mpz_tdiv_ui</code>. If the quotient is only rarely wanted then it’s
|
||
|
probably best to just take a remainder and then go back and calculate the
|
||
|
quotient if and when it’s wanted (<code>mpz_divexact_ui</code> can be used if the
|
||
|
remainder is zero).
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Rational Arithmetic</dt>
|
||
|
<dd><a name="index-Rational-arithmetic"></a>
|
||
|
<p>The <code>mpq</code> functions operate on <code>mpq_t</code> values with no common factors
|
||
|
in the numerator and denominator. Common factors are checked-for and cast out
|
||
|
as necessary. In general, cancelling factors every time is the best approach
|
||
|
since it minimizes the sizes for subsequent operations.
|
||
|
</p>
|
||
|
<p>However, applications that know something about the factorization of the
|
||
|
values they’re working with might be able to avoid some of the GCDs used for
|
||
|
canonicalization, or swap them for divisions. For example when multiplying by
|
||
|
a prime it’s enough to check for factors of it in the denominator instead of
|
||
|
doing a full GCD. Or when forming a big product it might be known that very
|
||
|
little cancellation will be possible, and so canonicalization can be left to
|
||
|
the end.
|
||
|
</p>
|
||
|
<p>The <code>mpq_numref</code> and <code>mpq_denref</code> macros give access to the
|
||
|
numerator and denominator to do things outside the scope of the supplied
|
||
|
<code>mpq</code> functions. See <a href="Applying-Integer-Functions.html#Applying-Integer-Functions">Applying Integer Functions</a>.
|
||
|
</p>
|
||
|
<p>The canonical form for rationals allows mixed-type <code>mpq_t</code> and integer
|
||
|
additions or subtractions to be done directly with multiples of the
|
||
|
denominator. This will be somewhat faster than <code>mpq_add</code>. For example,
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">/* mpq increment */
|
||
|
mpz_add (mpq_numref(q), mpq_numref(q), mpq_denref(q));
|
||
|
|
||
|
/* mpq += unsigned long */
|
||
|
mpz_addmul_ui (mpq_numref(q), mpq_denref(q), 123UL);
|
||
|
|
||
|
/* mpq -= mpz */
|
||
|
mpz_submul (mpq_numref(q), mpq_denref(q), z);
|
||
|
</pre></div>
|
||
|
|
||
|
</dd>
|
||
|
<dt>Number Sequences</dt>
|
||
|
<dd><a name="index-Number-sequences"></a>
|
||
|
<p>Functions like <code>mpz_fac_ui</code>, <code>mpz_fib_ui</code> and <code>mpz_bin_uiui</code>
|
||
|
are designed for calculating isolated values. If a range of values is wanted
|
||
|
it’s probably best to call to get a starting point and iterate from there.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>Text Input/Output</dt>
|
||
|
<dd><a name="index-Text-input_002foutput"></a>
|
||
|
<p>Hexadecimal or octal are suggested for input or output in text form.
|
||
|
Power-of-2 bases like these can be converted much more efficiently than other
|
||
|
bases, like decimal. For big numbers there’s usually nothing of particular
|
||
|
interest to be seen in the digits, so the base doesn’t matter much.
|
||
|
</p>
|
||
|
<p>Maybe we can hope octal will one day become the normal base for everyday use,
|
||
|
as proposed by King Charles XII of Sweden and later reformers.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<div class="header">
|
||
|
<p>
|
||
|
Next: <a href="Debugging.html#Debugging" accesskey="n" rel="next">Debugging</a>, Previous: <a href="Demonstration-Programs.html#Demonstration-Programs" accesskey="p" rel="prev">Demonstration Programs</a>, Up: <a href="GMP-Basics.html#GMP-Basics" accesskey="u" rel="up">GMP Basics</a> [<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|