@ -21,22 +21,22 @@
<title>What is <acronym>JIT</acronym> compilation?</title>
<title>What is <acronym>JIT</acronym> compilation?</title>
<para>
<para>
Just-in-time compilation (<acronym>JIT</acronym>) is the process of turning
Just-in-Time (<acronym>JIT</acronym>) compilation is the process of turning
some form of interpreted program evaluation into a native program, and
some form of interpreted program evaluation into a native program, and
doing so at run time.
doing so at run time.
For example, instead of using general-purpose code that can evaluate
For example, instead of using a facility that can evaluate arbitrary SQL
arbitrary SQL expressions to evaluate a particular SQL predicate
expressions to evaluate an SQL predicate like <literal>WHERE a.col =
like <literal>WHERE a.col = 3</literal>, it is possible to generate a
3</literal>, it is possible to generate a function than can be natively
function that is specific to that expression and can be natively executed
executed by the CPU that just handles that expression , yielding a speedup.
by the CPU, yielding a speedup.
</para>
</para>
<para>
<para>
<productname>PostgreSQL</productname> has builtin support to perform
<productname>PostgreSQL</productname> has builtin support to perform
<acronym>JIT</acronym> compilation using <ulink
<acronym>JIT</acronym> compilation using <ulink
url="https://llvm.org/"><productname>LLVM</productname></ulink> when
url="https://llvm.org/"><productname>LLVM</productname></ulink> when
<productname>PostgreSQL</productname> wa s built with
<productname>PostgreSQL</productname> i s built with
<literal>--with-llvm</literal> (see <xref linkend="configure-with-llvm"/>) .
<link linkend="configure-with-llvm"><literal>--with-llvm</literal></link> .
</para>
</para>
<para>
<para>
@ -64,33 +64,32 @@
</para>
</para>
</sect2>
</sect2>
<sect2 id="jit-optimization">
<title>Optimization</title>
<para>
<productname>LLVM</productname> has support for optimizing generated
code. Some of the optimizations are cheap enough to be performed whenever
<acronym>JIT</acronym> is used, while others are only beneficial for
longer running queries.
See <ulink url="https://llvm.org/docs/Passes.html#transform-passes"/> for
more details about optimizations.
</para>
</sect2>
<sect2 id="jit-inlining">
<sect2 id="jit-inlining">
<title>Inlining</title>
<title>Inlining</title>
<para>
<para>
<productname>PostgreSQL</productname> is very extensible and allows new
<productname>PostgreSQL</productname> is very extensible and allows new
data types, functions, operators and other database objects to be defined;
data types, functions, operators and other database objects to be defined;
see <xref linkend="extend"/>. In fact the built-in one s are implemented
see <xref linkend="extend"/>. In fact the built-in objects are implemented
using nearly the same mechanisms. This extensibility implies some
using nearly the same mechanisms. This extensibility implies some
overhead, for example due to function calls (see <xref linkend="xfunc"/>).
overhead, for example due to function calls (see <xref linkend="xfunc"/>).
To reduce that overhead <acronym>JIT</acronym> compilation can inline the
To reduce that overhead, <acronym>JIT</acronym> compilation can inline the
body for small functions into the expression using them. That allows a
bodies of small functions into the expressions using them. That allows a
significant percentage of the overhead to be optimized away.
significant percentage of the overhead to be optimized away.
</para>
</para>
</sect2>
</sect2>
<sect2 id="jit-optimization">
<title>Optimization</title>
<para>
<productname>LLVM</productname> has support for optimizing generated
code. Some of the optimizations are cheap enough to be performed whenever
<acronym>JIT</acronym> is used, while others are only beneficial for
longer-running queries.
See <ulink url="https://llvm.org/docs/Passes.html#transform-passes"/> for
more details about optimizations.
</para>
</sect2>
</sect1>
</sect1>
<sect1 id="jit-decision">
<sect1 id="jit-decision">
@ -98,50 +97,46 @@
<para>
<para>
<acronym>JIT</acronym> compilation is beneficial primarily for long-running
<acronym>JIT</acronym> compilation is beneficial primarily for long-running
CPU bound queries. Frequently these will be analytical queries. For short
CPU- bound queries. Frequently these will be analytical queries. For short
queries the added overhead of performing <acronym>JIT</acronym> compilation
queries the added overhead of performing <acronym>JIT</acronym> compilation
will often be higher than the time it can save.
will often be higher than the time it can save.
</para>
</para>
<para>
<para>
To determine whether <acronym>JIT</acronym> compilation is used, the total
To determine whether <acronym>JIT</acronym> compilation should be used,
cost of a query (see <xref linkend="planner-stats-details"/> and <xref
the total estimated cost of a query (see
linkend="runtime-config-query-constants"/>) is used.
<xref linkend="planner-stats-details"/> and
</para>
<xref linkend="runtime-config-query-constants"/>) is used.
The estimated cost of the query will be compared with the setting of <xref
<para>
The cost of the query will be compared with the setting of <xref
linkend="guc-jit-above-cost"/>. If the cost is higher,
linkend="guc-jit-above-cost"/>. If the cost is higher,
<acronym>JIT</acronym> compilation will be performed.
<acronym>JIT</acronym> compilation will be performed.
</para>
Two further decisions are then needed.
Firstly, if the estimated cost is more
<para>
than the setting of <xref linkend="guc-jit-inline-above-cost"/>, short
If the planner, based on the above criterion, decided that
functions and operators used in the query will be inlined.
<acronym>JIT</acronym> compilation is beneficial, two further decisions are
Secondly, if the estimated cost is more than the setting of <xref
made. Firstly, if the query is more costly than the setting of <xref
linkend="guc-jit-optimize-above-cost"/>, expensive optimizations are
linkend="guc-jit-optimize-above-cost"/>, expensive optimizations are
used to improve the generated code. Secondly, if the query is more costly
applied to improve the generated code.
than the setting of <xref linkend="guc-jit-inline-above-cost"/>, short functions
Each of these options increases the <acronym>JIT</acronym> compilation
and operators used in the query will be inlined. Both of these operations
overhead, but can reduce query execution time considerably.
increase the <acronym>JIT</acronym> overhead, but can reduce query
execution time considerably.
</para>
</para>
<para>
<para>
This cost based decision will be made at plan time, not execution
These cost-based decisions will be made at plan time, not execution
time. This means that when prepared statements are in use, and the generic
time. This means that when prepared statements are in use, and a generic
plan is used (see <xref linkend="sql-prepare-notes"/>), the values of the
plan is used (see <xref linkend="sql-prepare"/>), the values of the
configuration parameters set at prepare time take effect, not the settings at execution time.
configuration parameters in effect at prepare time control the decisions,
not the settings at execution time.
</para>
</para>
<note>
<note>
<para>
<para>
If <xref linkend="guc-jit"/> is set to <literal>off</literal>, or no
If <xref linkend="guc-jit"/> is set to <literal>off</literal>, or if no
<acronym>JIT</acronym> implementation is available (for example because
<acronym>JIT</acronym> implementation is available (for example because
the server was compiled without <literal>--with-llvm</literal>),
the server was compiled without <literal>--with-llvm</literal>),
<acronym>JIT</acronym> will not be performed, even if considered to be
<acronym>JIT</acronym> will not be performed, even if it would be
beneficial based on the above criteria. Setting <xref linkend="guc-jit"/>
beneficial based on the above criteria. Setting <xref linkend="guc-jit"/>
to <literal>off</literal> takes effect both at plan and at execution time.
to <literal>off</literal> has effects at both plan and execution time.
</para>
</para>
</note>
</note>
@ -160,9 +155,9 @@
(4 rows)
(4 rows)
</screen>
</screen>
Given the cost of the plan, it is entirely reasonable that no
Given the cost of the plan, it is entirely reasonable that no
<acronym>JIT</acronym> was used, the cost of <acronym>JIT</acronym> would
<acronym>JIT</acronym> was used; the cost of <acronym>JIT</acronym> would
have been bigger than the savings. Adjusting the cost limits will lead to
have been bigger than the potential savings. Adjusting the cost limits
<acronym>JIT</acronym> use:
will lead to <acronym>JIT</acronym> use:
<screen>
<screen>
=# SET jit_above_cost = 10;
=# SET jit_above_cost = 10;
SET
SET
@ -184,9 +179,9 @@ SET
</screen>
</screen>
As visible here, <acronym>JIT</acronym> was used, but inlining and
As visible here, <acronym>JIT</acronym> was used, but inlining and
expensive optimization were not. If <xref
expensive optimization were not. If <xref
linkend="guc-jit-optimize-above-cost"/>, <xref
linkend="guc-jit-inline-above-cost"/> or <xref
linkend="guc-jit-inline-above-cost"/> were lowered, just like <xref
linkend="guc-jit-optimize-above-cost"/> were also lowered,
linkend="guc-jit-above-cost"/>, that would change.
that would change.
</para>
</para>
</sect1>
</sect1>
@ -194,58 +189,53 @@ SET
<title>Configuration</title>
<title>Configuration</title>
<para>
<para>
The configuration variable
<xref linkend="guc-jit"/> determines whether <acronym>JIT</acronym>
<xref linkend="guc-jit"/> determines whether <acronym>JIT</acronym>
compilation is enabled or disabled.
compilation is enabled or disabled.
</para>
If it is enabled, the configuration variables
<para>
As explained in <xref linkend="jit-decision"/> the configuration variables
<xref linkend="guc-jit-above-cost"/>, <xref
<xref linkend="guc-jit-above-cost"/>, <xref
linkend="guc-jit-optimize-above-cost"/>, <xref
linkend="guc-jit-inline-above-cost"/>, and <xref
linkend="guc-jit-inline-above-cost"/> decide whether <acronym>JIT</acronym>
linkend="guc-jit-optimize-above-cost"/> determine
compilation is performed for a query, and how much effort is spent doing
whether <acronym>JIT</acronym> compilation is performed for a query,
so.
and how much effort is spent doing so.
</para>
</para>
<para>
<para>
For development and debugging purposes a few additional configuration parameters exist. <xref
<xref linkend="guc-jit-provider"/> determines which <acronym>JIT</acronym>
linkend="guc-jit-dump-bitcode"/> allows the generated bitcode to be
implementation is used. It is rarely required to be changed. See <xref
inspected. <xref linkend="guc-jit-debugging-support"/> allows GDB to see
linkend="jit-pluggable"/>.
generated functions. <xref linkend="guc-jit-profiling-support"/> emits
information so the <productname>perf</productname> profiler can interpret
<acronym>JIT</acronym> generated functions sensibly.
</para>
</para>
<para>
<para>
<xref linkend="guc-jit-provider"/> determines which <acronym>JIT</acronym>
For development and debugging purposes a few additional configuration
implementation is used. It rarely is required to be changed. See <xref
parameters exist, as described in
linkend="jit-pluggable "/>.
<xref linkend="runtime-config-developer "/>.
</para>
</para>
</sect1>
</sect1>
<sect1 id="jit-extensibility" xreflabel="JIT Extensibility" >
<sect1 id="jit-extensibility">
<title>Extensibility</title>
<title>Extensibility</title>
<sect2 id="jit-extensibility-bitcode">
<sect2 id="jit-extensibility-bitcode">
<title>Inlining Support for Extensions</title>
<title>Inlining Support for Extensions</title>
<para>
<para>
<productname>PostgreSQL</productname>'s <acronym>JIT</acronym>
<productname>PostgreSQL</productname>'s <acronym>JIT</acronym>
implementation can inline the implementation of operators and functions
implementation can inline the bodies of functions
( of type <literal>C</literal> and <literal>internal</literal>). See <xref
of types <literal>C</literal> and <literal>internal</literal>, as well as
linkend="jit-inlining"/>. To do so for functions in extensions, the
operators based on such functions. To do so for functions in extensions,
definition of these functions needs to be made available. When using <link
the definitions of those functions need to be made available.
linkend="extend-pgxs">PGXS</link> to build an extension against a server
When using <link linkend="extend-pgxs">PGXS</link> to build an extension
that has been compiled with LLVM support, the relevant files will b e
against a server that has been compiled with LLVM JIT support, the
installed automatically.
relevant files will be built and installed automatically.
</para>
</para>
<para>
<para>
The relevant files have to be installed into
The relevant files have to be installed into
<filename>$pkglibdir/bitcode/$extension/</filename> and a summary of them
<filename>$pkglibdir/bitcode/$extension/</filename> and a summary of them
to <filename>$pkglibdir/bitcode/$extension.index.bc</filename>, where
in to <filename>$pkglibdir/bitcode/$extension.index.bc</filename>, where
<literal>$pkglibdir</literal> is the directory returned by
<literal>$pkglibdir</literal> is the directory returned by
<literal>pg_config --pkglibdir</literal> and <literal>$extension</literal>
<literal>pg_config --pkglibdir</literal> and <literal>$extension</literal>
the base name of the extension's shared library.
is the base name of the extension's shared library.
<note>
<note>
<para>
<para>
@ -258,14 +248,16 @@ SET
</sect2>
</sect2>
<sect2 id="jit-pluggable">
<sect2 id="jit-pluggable">
<title>Pluggable <acronym>JIT</acronym> Provider</title>
<title>Pluggable <acronym>JIT</acronym> Providers </title>
<para>
<para>
<productname>PostgreSQL</productname> provides a <acronym>JIT</acronym>
<productname>PostgreSQL</productname> provides a <acronym>JIT</acronym>
implementation based on <productname>LLVM</productname>. The interface to
implementation based on <productname>LLVM</productname>. The interface to
the <acronym>JIT</acronym> provider is pluggable and the provider can be
the <acronym>JIT</acronym> provider is pluggable and the provider can be
changed without recompiling. The provider is chosen via the setting <xref
changed without recompiling (although currently, the build process only
linkend="guc-jit-provider"/>.
provides inlining support data for <productname>LLVM</productname>).
The active provider is chosen via the setting
<xref linkend="guc-jit-provider"/>.
</para>
</para>
<sect3>
<sect3>
@ -275,10 +267,10 @@ SET
named shared library. The normal library search path is used to locate
named shared library. The normal library search path is used to locate
the library. To provide the required <acronym>JIT</acronym> provider
the library. To provide the required <acronym>JIT</acronym> provider
callbacks and to indicate that the library is actually a
callbacks and to indicate that the library is actually a
<acronym>JIT</acronym> provider it needs to provide a function named
<acronym>JIT</acronym> provider, it needs to provide a C function named
<function>_PG_jit_provider_init</function>. This function is passed a
<function>_PG_jit_provider_init</function>. This function is passed a
struct that needs to be filled with the callback function pointers for
struct that needs to be filled with the callback function pointers for
individual actions.
individual actions:
<programlisting>
<programlisting>
struct JitProviderCallbacks
struct JitProviderCallbacks
{
{
@ -286,6 +278,7 @@ struct JitProviderCallbacks
JitProviderReleaseContextCB release_context;
JitProviderReleaseContextCB release_context;
JitProviderCompileExprCB compile_expr;
JitProviderCompileExprCB compile_expr;
};
};
extern void _PG_jit_provider_init(JitProviderCallbacks *cb);
extern void _PG_jit_provider_init(JitProviderCallbacks *cb);
</programlisting>
</programlisting>
</para>
</para>