Constant gmp_mpfr_sys::C::GMP::GMP_Basics [−][src]
pub const GMP_Basics: ();
This constant is a place-holder for documentation; do not use it in code.
Next: Reporting Bugs, Previous: Installing GMP, Up: Top [Index]
3 GMP Basics
Using functions, macros, data types, etc. not documented in this manual is strongly discouraged. If you do so your application is guaranteed to be incompatible with future versions of GMP.
Next: Nomenclature and Types, Previous: GMP Basics, Up: GMP Basics [Index]
3.1 Headers and Libraries
All declarations needed to use GMP are collected in the include file gmp.h. It is designed to work with both C and C++ compilers.
#include <gmp.h>
Note however that prototypes for GMP functions with FILE *
parameters
are only provided if <stdio.h>
is included too.
#include <stdio.h> #include <gmp.h>
Likewise <stdarg.h>
is required for prototypes with va_list
parameters, such as gmp_vprintf
. And <obstack.h>
for prototypes
with struct obstack
parameters, such as gmp_obstack_printf
, when
available.
All programs using GMP must link against the libgmp library. On a typical Unix-like system this can be done with ‘-lgmp’, for example
gcc myprogram.c -lgmp
GMP C++ functions are in a separate libgmpxx library. This is built and installed if C++ support has been enabled (see Build Options). For example,
g++ mycxxprog.cc -lgmpxx -lgmp
GMP is built using Libtool and an application can use that to link if desired, see GNU Libtool in GNU Libtool.
If GMP has been installed to a non-standard location then it may be necessary to use ‘-I’ and ‘-L’ compiler options to point to the right directories, and some sort of run-time path for a shared library.
Next: Function Classes, Previous: Headers and Libraries, Up: GMP Basics [Index]
3.2 Nomenclature and Types
In this manual, integer usually means a multiple precision integer, as
defined by the GMP library. The C data type for such integers is mpz_t
.
Here are some examples of how to declare such integers:
mpz_t sum; struct foo { mpz_t x, y; }; mpz_t vec[20];
Rational number means a multiple precision fraction. The C data type
for these fractions is mpq_t
. For example:
mpq_t quotient;
Floating point number or Float for short, is an arbitrary precision
mantissa with a limited precision exponent. The C data type for such objects
is mpf_t
. For example:
mpf_t fp;
The floating point functions accept and return exponents in the C type
mp_exp_t
. Currently this is usually a long
, but on some systems
it’s an int
for efficiency.
A limb means the part of a multi-precision number that fits in a single
machine word. (We chose this word because a limb of the human body is
analogous to a digit, only larger, and containing several digits.) Normally a
limb is 32 or 64 bits. The C data type for a limb is mp_limb_t
.
Counts of limbs of a multi-precision number represented in the C type
mp_size_t
. Currently this is normally a long
, but on some
systems it’s an int
for efficiency, and on some systems it will be
long long
in the future.
Counts of bits of a multi-precision number are represented in the C type
mp_bitcnt_t
. Currently this is always an unsigned long
, but on
some systems it will be an unsigned long long
in the future.
Random state means an algorithm selection and current state data. The C
data type for such objects is gmp_randstate_t
. For example:
gmp_randstate_t rstate;
Also, in general mp_bitcnt_t
is used for bit counts and ranges, and
size_t
is used for byte or character counts.
Next: Variable Conventions, Previous: Nomenclature and Types, Up: GMP Basics [Index]
3.3 Function Classes
There are six classes of functions in the GMP library:
- Functions for signed integer arithmetic, with names beginning with
mpz_
. The associated type ismpz_t
. There are about 150 functions in this class. (see Integer Functions) - Functions for rational number arithmetic, with names beginning with
mpq_
. The associated type ismpq_t
. There are about 35 functions in this class, but the integer functions can be used for arithmetic on the numerator and denominator separately. (see Rational Number Functions) - Functions for floating-point arithmetic, with names beginning with
mpf_
. The associated type ismpf_t
. There are about 70 functions is this class. (see Floating-point Functions) - Fast low-level functions that operate on natural numbers. These are used by
the functions in the preceding groups, and you can also call them directly
from very time-critical user programs. These functions’ names begin with
mpn_
. The associated type is array ofmp_limb_t
. There are about 60 (hard-to-use) functions in this class. (see Low-level Functions) - Miscellaneous functions. Functions for setting up custom allocation and functions for generating random numbers. (see Custom Allocation, and see Random Number Functions)
Next: Parameter Conventions, Previous: Function Classes, Up: GMP Basics [Index]
3.4 Variable Conventions
GMP functions generally have output arguments before input arguments. This notation is by analogy with the assignment operator.
GMP lets you use the same variable for both input and output in one call. For
example, the main function for integer multiplication, mpz_mul
, can be
used to square x
and put the result back in x
with
mpz_mul (x, x, x);
Before you can assign to a GMP variable, you need to initialize it by calling one of the special initialization functions. When you’re done with a variable, you need to clear it out, using one of the functions for that purpose. Which function to use depends on the type of variable. See the chapters on integer functions, rational number functions, and floating-point functions for details.
A variable should only be initialized once, or at least cleared between each initialization. After a variable has been initialized, it may be assigned to any number of times.
For efficiency reasons, avoid excessive initializing and clearing. In general, initialize near the start of a function and clear near the end. For example,
void foo (void) { mpz_t n; int i; mpz_init (n); for (i = 1; i < 100; i++) { mpz_mul (n, …); mpz_fdiv_q (n, …); … } mpz_clear (n); }
GMP types like mpz_t
are implemented as one-element arrays of certain
structures. Declaring a variable creates an object with the fields GMP needs,
but variables are normally manipulated by using the pointer to the object. For
both behavior and efficiency reasons, it is discouraged to make copies of the
GMP object itself (either directly or via aggregate objects containing such GMP
objects). If copies are done, all of them must be used read-only; using a copy
as the output of some function will invalidate all the other copies. Note that
the actual fields in each mpz_t
etc are for internal use only and should
not be accessed directly by code that expects to be compatible with future GMP
releases.
Next: Memory Management, Previous: Variable Conventions, Up: GMP Basics [Index]
3.5 Parameter Conventions
When a GMP variable is used as a function parameter, it’s effectively a
call-by-reference, meaning that when the function stores a value there it will
change the original in the caller. Parameters which are input-only can be
designated const
to provoke a compiler error or warning on attempting to
modify them.
When a function is going to return a GMP result, it should designate a
parameter that it sets, like the library functions do. More than one value
can be returned by having more than one output parameter, again like the
library functions. A return
of an mpz_t
etc doesn’t return the
object, only a pointer, and this is almost certainly not what’s wanted.
Here’s an example accepting an mpz_t
parameter, doing a calculation,
and storing the result to the indicated parameter.
void foo (mpz_t result, const mpz_t param, unsigned long n) { unsigned long i; mpz_mul_ui (result, param, n); for (i = 1; i < n; i++) mpz_add_ui (result, result, i*7); } int main (void) { mpz_t r, n; mpz_init (r); mpz_init_set_str (n, "123456", 0); foo (r, n, 20L); gmp_printf ("%Zd\n", r); return 0; }
Our function foo
works even if its caller passes the same variable for
param
and result
, just like the library functions. But
sometimes it’s tricky to make that work, and an application might not want to
bother supporting that sort of thing.
Since GMP types are implemented as one-element arrays, using a GMP variable as a parameter passes a pointer to the object. Hence the call-by-reference.
Next: Reentrancy, Previous: Parameter Conventions, Up: GMP Basics [Index]
3.6 Memory Management
The GMP types like mpz_t
are small, containing only a couple of sizes,
and pointers to allocated data. Once a variable is initialized, GMP takes
care of all space allocation. Additional space is allocated whenever a
variable doesn’t have enough.
mpz_t
and mpq_t
variables never reduce their allocated space.
Normally this is the best policy, since it avoids frequent reallocation.
Applications that need to return memory to the heap at some particular point
can use mpz_realloc2
, or clear variables no longer needed.
mpf_t
variables, in the current implementation, use a fixed amount of
space, determined by the chosen precision and allocated at initialization, so
their size doesn’t change.
All memory is allocated using malloc
and friends by default, but this
can be changed, see Custom Allocation. Temporary memory on the stack is
also used (via alloca
), but this can be changed at build-time if
desired, see Build Options.
Next: Useful Macros and Constants, Previous: Memory Management, Up: GMP Basics [Index]
3.7 Reentrancy
GMP is reentrant and thread-safe, with some exceptions:
- If configured with --enable-alloca=malloc-notreentrant (or with
--enable-alloca=notreentrant when
alloca
is not available), then naturally GMP is not reentrant. -
mpf_set_default_prec
andmpf_init
use a global variable for the selected precision.mpf_init2
can be used instead, and in the C++ interface an explicit precision to thempf_class
constructor. -
mpz_random
and the other old random number functions use a global random state and are hence not reentrant. The newer random number functions that accept agmp_randstate_t
parameter can be used instead. -
gmp_randinit
(obsolete) returns an error indication through a global variable, which is not thread safe. Applications are advised to usegmp_randinit_default
orgmp_randinit_lc_2exp
instead. -
mp_set_memory_functions
uses global variables to store the selected memory allocation functions. - If the memory allocation functions set by a call to
mp_set_memory_functions
(ormalloc
and friends by default) are not reentrant, then GMP will not be reentrant either. - If the standard I/O functions such as
fwrite
are not reentrant then the GMP I/O functions using them will not be reentrant either. - It’s safe for two threads to read from the same GMP variable simultaneously,
but it’s not safe for one to read while another might be writing, nor for
two threads to write simultaneously. It’s not safe for two threads to
generate a random number from the same
gmp_randstate_t
simultaneously, since this involves an update of that variable.
Next: Compatibility with older versions, Previous: Reentrancy, Up: GMP Basics [Index]
3.8 Useful Macros and Constants
- Global Constant: const int mp_bits_per_limb
-
The number of bits per limb.
- Macro: __GNU_MP_VERSION
- Macro: __GNU_MP_VERSION_MINOR
- Macro: __GNU_MP_VERSION_PATCHLEVEL
-
The major and minor GMP version, and patch level, respectively, as integers. For GMP i.j, these numbers will be i, j, and 0, respectively. For GMP i.j.k, these numbers will be i, j, and k, respectively.
- Global Constant: const char * const gmp_version
-
The GMP version number, as a null-terminated string, in the form “i.j.k”. This release is
"6.2.0"
. Note that the format “i.j” was used, before version 4.3.0, when k was zero.
- Macro: __GMP_CC
- Macro: __GMP_CFLAGS
The compiler and compiler flags, respectively, used when compiling GMP, as strings.
Next: Demonstration Programs, Previous: Useful Macros and Constants, Up: GMP Basics [Index]
3.9 Compatibility with older versions
This version of GMP is upwardly binary compatible with all 5.x, 4.x, and 3.x versions, and upwardly compatible at the source level with all 2.x versions, with the following exceptions.
-
mpn_gcd
had its source arguments swapped as of GMP 3.0, for consistency with othermpn
functions. -
mpf_get_prec
counted precision slightly differently in GMP 3.0 and 3.0.1, but in 3.1 reverted to the 2.x style. -
mpn_bdivmod
, documented as preliminary in GMP 4, has been removed.
There are a number of compatibility issues between GMP 1 and GMP 2 that of course also apply when porting applications from GMP 1 to GMP 5. Please see the GMP 2 manual for details.
Next: Efficiency, Previous: Compatibility with older versions, Up: GMP Basics [Index]
3.10 Demonstration programs
The demos subdirectory has some sample programs using GMP. These aren’t built or installed, but there’s a Makefile with rules for them. For instance,
make pexpr ./pexpr 68^975+10
The following programs are provided
- ‘pexpr’ is an expression evaluator, the program used on the GMP web page.
-
The ‘calc’ subdirectory has a similar but simpler evaluator using
lex
andyacc
. - The ‘expr’ subdirectory is yet another expression evaluator, a library designed for ease of use within a C program. See demos/expr/README for more information.
- ‘factorize’ is a Pollard-Rho factorization program.
- ‘isprime’ is a command-line interface to the
mpz_probab_prime_p
function. - ‘primes’ counts or lists primes in an interval, using a sieve.
- ‘qcn’ is an example use of
mpz_kronecker_ui
to estimate quadratic class numbers. - The ‘perl’ subdirectory is a comprehensive perl interface to GMP. See demos/perl/INSTALL for more information. Documentation is in POD format in demos/perl/GMP.pm.
As an aside, consideration has been given at various times to some sort of expression evaluation within the main GMP library. Going beyond something minimal quickly leads to matters like user-defined functions, looping, fixnums for control variables, etc, which are considered outside the scope of GMP (much closer to language interpreters or compilers, See Language Bindings.) Something simple for program input convenience may yet be a possibility, a combination of the expr demo and the pexpr tree back-end perhaps. But for now the above evaluators are offered as illustrations.
Next: Debugging, Previous: Demonstration Programs, Up: GMP Basics [Index]
3.11 Efficiency
- Small Operands
-
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.
- Static Linking
-
On some CPUs, in particular the x86s, the static libgmp.a should be used for maximum speed, since the PIC code in the shared libgmp.so 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.
- Initializing and Clearing
-
Avoid excessive initializing and clearing of variables, since this can be quite time consuming, especially in comparison to otherwise fast operations like addition.
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.
- Reallocations
-
An
mpz_t
ormpq_t
variable used to hold successively increasing values will have its memory repeatedlyrealloc
ed, which could be quite slow or could fragment memory, depending on the C library. If an application can estimate the final size thenmpz_init2
ormpz_realloc2
can be called to allocate the necessary space from the beginning (see Initializing Integers).It doesn’t matter if a size set with
mpz_init2
ormpz_realloc2
is too small, since all functions will do a further reallocation if necessary. Badly overestimating memory required will waste space though. 2exp
Functions-
It’s up to an application to call functions like
mpz_mul_2exp
when appropriate. General purpose functions likempz_mul
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. ui
andsi
Functions-
The
ui
functions and the small number ofsi
functions exist for convenience and should be used where applicable. But if for example anmpz_t
contains a value that fits in anunsigned long
there’s no need extract it and call aui
function, just use the regularmpz
function. - In-Place Operations
-
mpz_abs
,mpq_abs
,mpf_abs
,mpz_neg
,mpq_neg
andmpf_neg
are fast when used for in-place operations likempz_abs(x,x)
, since in the current implementation only a single field ofx
needs changing. On suitable compilers (GCC for instance) this is inlined too.mpz_add_ui
,mpz_sub_ui
,mpf_add_ui
andmpf_sub_ui
benefit from an in-place operation likempz_add_ui(x,x,y)
, since usually only one or two limbs ofx
will need to be changed. The same applies to the full precisionmpz_add
etc ify
is small. Ify
is big then cache locality may be helped, but that’s all.mpz_mul
is currently the opposite, a separate destination is slightly better. A call likempz_mul(x,x,y)
will, unlessy
is only one limb, make a temporary copy ofx
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.mpz_set
,mpq_set
,mpq_set_num
,mpf_set
, etc, make no attempt to recognise a copy of something to itself, so a call likempz_set(x,x)
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.if (x != y) mpz_set (x, y);
Note that it’s never worth introducing extra
mpz_set
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. - Divisibility Testing (Small Integers)
-
mpz_divisible_ui_p
andmpz_congruent_ui_p
are the best functions for testing whether anmpz_t
is divisible by an individual small integer. They use an algorithm which is faster thanmpz_tdiv_ui
, but which gives no useful information about the actual remainder, only whether it’s zero (or a particular value).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 23*29*31 = 20677 and then test that.
The division functions like
mpz_tdiv_q_ui
which give a quotient as well as a remainder are generally a little slower than the remainder-only functions likempz_tdiv_ui
. 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 (mpz_divexact_ui
can be used if the remainder is zero). - Rational Arithmetic
-
The
mpq
functions operate onmpq_t
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.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.
The
mpq_numref
andmpq_denref
macros give access to the numerator and denominator to do things outside the scope of the suppliedmpq
functions. See Applying Integer Functions.The canonical form for rationals allows mixed-type
mpq_t
and integer additions or subtractions to be done directly with multiples of the denominator. This will be somewhat faster thanmpq_add
. For 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);
- Number Sequences
-
Functions like
mpz_fac_ui
,mpz_fib_ui
andmpz_bin_uiui
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. - Text Input/Output
-
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.
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.
Next: Profiling, Previous: Efficiency, Up: GMP Basics [Index]
3.12 Debugging
- Stack Overflow
-
Depending on the system, a segmentation violation or bus error might be the only indication of stack overflow. See ‘--enable-alloca’ choices in Build Options, for how to address this.
In new enough versions of GCC, ‘-fstack-check’ may be able to ensure an overflow is recognised by the system before too much damage is done, or ‘-fstack-limit-symbol’ or ‘-fstack-limit-register’ may be able to add checking if the system itself doesn’t do any (see Options for Code Generation in Using the GNU Compiler Collection (GCC)). These options must be added to the ‘CFLAGS’ used in the GMP build (see Build Options), adding them just to an application will have no effect. Note also they’re a slowdown, adding overhead to each function call and each stack allocation.
- Heap Problems
-
The most likely cause of application problems with GMP is heap corruption. Failing to
init
GMP variables will have unpredictable effects, and corruption arising elsewhere in a program may well affect GMP. Initializing GMP variables more than once or failing to clear them will cause memory leaks.In all such cases a
malloc
debugger is recommended. On a GNU or BSD system the standard C librarymalloc
has some diagnostic facilities, see Allocation Debugging in The GNU C Library Reference Manual, or ‘man 3 malloc’. Other possibilities, in no particular order, includehttp://cs.ecs.baylor.edu/~donahoo/tools/ccmalloc/ http://dmalloc.com/ https://wiki.gnome.org/Apps/MemProf
The GMP default allocation routines in memory.c also have a simple sentinel scheme which can be enabled with
#define DEBUG
in that file. This is mainly designed for detecting buffer overruns during GMP development, but might find other uses. - Stack Backtraces
-
On some systems the compiler options GMP uses by default can interfere with debugging. In particular on x86 and 68k systems ‘-fomit-frame-pointer’ is used and this generally inhibits stack backtracing. Recompiling without such options may help while debugging, though the usual caveats about it potentially moving a memory problem or hiding a compiler bug will apply.
- GDB, the GNU Debugger
-
A sample .gdbinit is included in the distribution, showing how to call some undocumented dump functions to print GMP variables from within GDB. Note that these functions shouldn’t be used in final application code since they’re undocumented and may be subject to incompatible changes in future versions of GMP.
- Source File Paths
GMP has multiple source files with the same name, in different directories. For example mpz, mpq and mpf each have an init.c. If the debugger can’t already determine the right one it may help to build with absolute paths on each C file. One way to do that is to use a separate object directory with an absolute path to the source directory.
cd /my/build/dir /my/source/dir/gmp-6.2.0/configure
This works via
VPATH
, and might require GNUmake
. Alternately it might be possible to change the.c.lo
rules appropriately.- Assertion Checking
-
The build option --enable-assert is available to add some consistency checks to the library (see Build Options). These are likely to be of limited value to most applications. Assertion failures are just as likely to indicate memory corruption as a library or compiler bug.
Applications using the low-level
mpn
functions, however, will benefit from --enable-assert since it adds checks on the parameters of most such functions, many of which have subtle restrictions on their usage. Note however that only the generic C code has checks, not the assembly code, so --disable-assembly should be used for maximum checking. - Temporary Memory Checking
The build option --enable-alloca=debug arranges that each block of temporary memory in GMP is allocated with a separate call to
malloc
(or the allocation function set withmp_set_memory_functions
).This can help a malloc debugger detect accesses outside the intended bounds, or detect memory not released. In a normal build, on the other hand, temporary memory is allocated in blocks which GMP divides up for its own use, or may be allocated with a compiler builtin
alloca
which will go nowhere near any malloc debugger hooks.- Maximum Debuggability
To summarize the above, a GMP build for maximum debuggability would be
./configure --disable-shared --enable-assert \ --enable-alloca=debug --disable-assembly CFLAGS=-g
For C++, add ‘--enable-cxx CXXFLAGS=-g’.
- Checker
-
The GCC checker (https://savannah.nongnu.org/projects/checker/) can be used with GMP. It contains a stub library which means GMP applications compiled with checker can use a normal GMP build.
A build of GMP with checking within GMP itself can be made. This will run very very slowly. On GNU/Linux for example,
./configure --disable-assembly CC=checkergcc
--disable-assembly must be used, since the GMP assembly code doesn’t support the checking scheme. The GMP C++ features cannot be used, since current versions of checker (0.9.9.1) don’t yet support the standard C++ library.
- Valgrind
-
Valgrind (http://valgrind.org/) is a memory checker for x86, ARM, MIPS, PowerPC, and S/390. It translates and emulates machine instructions to do strong checks for uninitialized data (at the level of individual bits), memory accesses through bad pointers, and memory leaks.
Valgrind does not always support every possible instruction, in particular ones recently added to an ISA. Valgrind might therefore be incompatible with a recent GMP or even a less recent GMP which is compiled using a recent GCC.
GMP’s assembly code sometimes promotes a read of the limbs to some larger size, for efficiency. GMP will do this even at the start and end of a multilimb operand, using naturally aligned operations on the larger type. This may lead to benign reads outside of allocated areas, triggering complaints from Valgrind. Valgrind’s option ‘--partial-loads-ok=yes’ should help.
- Other Problems
Any suspected bug in GMP itself should be isolated to make sure it’s not an application problem, see Reporting Bugs.
Next: Autoconf, Previous: Debugging, Up: GMP Basics [Index]
3.13 Profiling
Running a program under a profiler is a good way to find where it’s spending most time and where improvements can be best sought. The profiling choices for a GMP build are as follows.
- ‘--disable-profiling’
The default is to add nothing special for profiling.
It should be possible to just compile the mainline of a program with
-p
and useprof
to get a profile consisting of timer-based sampling of the program counter. Most of the GMP assembly code has the necessary symbol information.This approach has the advantage of minimizing interference with normal program operation, but on most systems the resolution of the sampling is quite low (10 milliseconds for instance), requiring long runs to get accurate information.
- ‘--enable-profiling=prof’
-
Build with support for the system
prof
, which means ‘-p’ added to the ‘CFLAGS’.This provides call counting in addition to program counter sampling, which allows the most frequently called routines to be identified, and an average time spent in each routine to be determined.
The x86 assembly code has support for this option, but on other processors the assembly routines will be as if compiled without ‘-p’ and therefore won’t appear in the call counts.
On some systems, such as GNU/Linux, ‘-p’ in fact means ‘-pg’ and in this case ‘--enable-profiling=gprof’ described below should be used instead.
- ‘--enable-profiling=gprof’
-
Build with support for
gprof
, which means ‘-pg’ added to the ‘CFLAGS’.This provides call graph construction in addition to call counting and program counter sampling, which makes it possible to count calls coming from different locations. For example the number of calls to
mpn_mul
frommpz_mul
versus the number frommpf_mul
. The program counter sampling is still flat though, so only a total time inmpn_mul
would be accumulated, not a separate amount for each call site.The x86 assembly code has support for this option, but on other processors the assembly routines will be as if compiled without ‘-pg’ and therefore not be included in the call counts.
On x86 and m68k systems ‘-pg’ and ‘-fomit-frame-pointer’ are incompatible, so the latter is omitted from the default flags in that case, which might result in poorer code generation.
Incidentally, it should be possible to use the
gprof
program with a plain ‘--enable-profiling=prof’ build. But in that case only the ‘gprof -p’ flat profile and call counts can be expected to be valid, not the ‘gprof -q’ call graph. - ‘--enable-profiling=instrument’
-
Build with the GCC option ‘-finstrument-functions’ added to the ‘CFLAGS’ (see Options for Code Generation in Using the GNU Compiler Collection (GCC)).
This inserts special instrumenting calls at the start and end of each function, allowing exact timing and full call graph construction.
This instrumenting is not normally a standard system feature and will require support from an external library, such as
This should be included in ‘LIBS’ during the GMP configure so that test programs will link. For example,
./configure --enable-profiling=instrument LIBS=-lfc
On a GNU system the C library provides dummy instrumenting functions, so programs compiled with this option will link. In this case it’s only necessary to ensure the correct library is added when linking an application.
The x86 assembly code supports this option, but on other processors the assembly routines will be as if compiled without ‘-finstrument-functions’ meaning time spent in them will effectively be attributed to their caller.
Next: Emacs, Previous: Profiling, Up: GMP Basics [Index]
3.14 Autoconf
Autoconf based applications can easily check whether GMP is installed. The
only thing to be noted is that GMP library symbols from version 3 onwards have
prefixes like __gmpz
. The following therefore would be a simple test,
AC_CHECK_LIB(gmp, __gmpz_init)
This just uses the default AC_CHECK_LIB
actions for found or not found,
but an application that must have GMP would want to generate an error if not
found. For example,
AC_CHECK_LIB(gmp, __gmpz_init, , [AC_MSG_ERROR([GNU MP not found, see https://gmplib.org/])])
If functions added in some particular version of GMP are required, then one of
those can be used when checking. For example mpz_mul_si
was added in
GMP 3.1,
AC_CHECK_LIB(gmp, __gmpz_mul_si, , [AC_MSG_ERROR( [GNU MP not found, or not 3.1 or up, see https://gmplib.org/])])
An alternative would be to test the version number in gmp.h using say
AC_EGREP_CPP
. That would make it possible to test the exact version,
if some particular sub-minor release is known to be necessary.
In general it’s recommended that applications should simply demand a new enough GMP rather than trying to provide supplements for features not available in past versions.
Occasionally an application will need or want to know the size of a type at
configuration or preprocessing time, not just with sizeof
in the code.
This can be done in the normal way with mp_limb_t
etc, but GMP 4.0 or
up is best for this, since prior versions needed certain ‘-D’ defines on
systems using a long long
limb. The following would suit Autoconf 2.50
or up,
AC_CHECK_SIZEOF(mp_limb_t, , [#include <gmp.h>])
Previous: Autoconf, Up: GMP Basics [Index]
3.15 Emacs
C-h C-i (info-lookup-symbol
) is a good way to find documentation
on C functions while editing (see Info Documentation Lookup in The Emacs Editor).
The GMP manual can be included in such lookups by putting the following in your .emacs,
(eval-after-load "info-look" '(let ((mode-value (assoc 'c-mode (assoc 'symbol info-lookup-alist)))) (setcar (nthcdr 3 mode-value) (cons '("(gmp)Function Index" nil "^ -.* " "\\>") (nth 3 mode-value)))))
Previous: Autoconf, Up: GMP Basics [Index]