compiler provides an important way both to speed up and also to work with Mathematica
computations. It does this by taking assumptions about the computations and rewriting them in more efficient ways. These assumptions limit the full generality of Mathematica
but are chosen to enhance important classes of computations. For example, computations involving machine-precision arithmetic are enhanced.
In addition to providing speed enhancements for Mathematica,
the compiler is also useful since it can analyze and process Mathematica
computations. This makes it the basis for useful features such as generating external code.
This tutorial will cover details about how the compiler works. It should help you to use it more effectively, for example, showing how to improve the performance of your computations.
A key way to use the Mathematica
compiler is with the function Compile
You can use the compiled function as any other Mathematica
function, passing it real number input.
However, if you pass the compiled function an input that is not a real number, a message is issued. Mathematica
still returns a result, but this has not used the compiler.
Comparison with Function
You can compare a compiled function with Function
. They are created with a similar command structure.
For machine inputs, they return the same result.
It is faster to use CompiledFunction
If the input is not a machine input, the compiled function issues a message before returning the result.
Compiled Function Internals
In general, Compile
creates a CompiledFunction
expression that contains a sequence of simple instructions for evaluating the compiled function. The instructions are chosen to be those that can be executed very efficiently by modern computer hardware and software libraries. The contents of the compiled function can be displayed by the input form.
You can get a view into how the compiled function executes with the
package. This is a key part of the Mathematica
code generation system, but it can also be useful to show you what the compiled function does.
To use the
package you have to load it.
will show details of the compiled function.
Calling the Compiler
compiler is called whenever a CompiledFunction
executes. These are created by calls to the Compile
function. In addition, a number of functions will attempt to use the compiler as part of their operation.
One important class includes many numerical computation functions, such as NDSolve
, and FindMinimum
. Typically, these have a Compiled
option that can be used to enable or disable use of the compiler. The default operation of these functions is make some analysis of the initial settings and the problem and use the compiler if these indicate it would be beneficial.
The following calls NDSolve
but does it without using the compiler.
Another class of uses of the compiler is from programming functions such as Table
. These analyze the input and use the compiler if this can be done without changing the result and if the time taken to create the compiled function does not cost too much.
In the following, the compiler is used. You can detect that the compiler was used because the result is a packed array.
Benefits of the Compiler
This section summarizes some of the benefits of the compiler.
A major benefit of the compiler is that it allows certain computations to be faster.
The following creates two expressions, using CompiledFunction
It is faster to use CompiledFunction
computations can be made faster still by using the code generator and by parallel computation.
The compiler works by creating a sequence of simple instructions for evaluating the compiled function. Mathematica
contains a virtual machine that can process these instructions. However, it can also use these instructions to create entire functions and programs written in other languages.
The following shows how to use ExportString
to convert a CompiledFunction
into a C code fragment.
Modern CPU architectures commonly provide multiple cores and these can be used by the compiler to execute a compiled function in parallel. The computations all run efficiently in multiple threads of execution, which is possible because of the simple instructions that the compiler generates.
The following demonstrates a compiled function running in parallel.
This shows the operation running sequentially; it takes twice as long.
is used to determine how many threads to be used.
For this computer $ProcessorCount
is 2 and this is why the parallel computation was twice the speed of the sequential computation.