From 8f32bacc006692e63f137924d5849b3cb9f2d4d3 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 15 Sep 2018 17:24:35 -0400 Subject: [PATCH] In v11, disable JIT by default (it's still enabled by default in HEAD). Per discussion, JIT isn't quite mature enough to ship enabled-by-default. I failed to resist the temptation to do a bunch of copy-editing on the related documentation. Also, clean up some inconsistencies in which section of config.sgml the JIT GUCs are documented in vs. what guc.c and postgresql.config.sample had. Discussion: https://postgr.es/m/20180914222657.mw25esrzbcnu6qlu@alap3.anarazel.de --- doc/src/sgml/config.sgml | 99 +++++----- doc/src/sgml/jit.sgml | 171 +++++++++--------- doc/src/sgml/release-11.sgml | 12 +- src/backend/jit/jit.c | 2 +- src/backend/utils/misc/guc.c | 2 +- src/backend/utils/misc/postgresql.conf.sample | 15 +- 6 files changed, 149 insertions(+), 152 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index bee4afbe4e..e1073ac6d3 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -4155,7 +4155,6 @@ ANY num_sync ( jit_above_cost (floating point) @@ -4164,33 +4163,16 @@ ANY num_sync ( ). Performing - JIT costs time but can accelerate query execution. - + Sets the query cost above which JIT compilation is activated, if + enabled (see ). + Performing JIT costs planning time but can + accelerate query execution. + Setting this to -1 disables JIT compilation. The default is 100000. - - jit_optimize_above_cost (floating point) - - jit_optimize_above_cost configuration parameter - - - - - Sets the planner's cutoff above which JIT compiled programs (see ) are optimized. Optimization initially - takes time, but can improve execution speed. It is not meaningful to - set this to a lower value than . - - The default is 500000. - - - - jit_inline_above_cost (floating point) @@ -4199,13 +4181,31 @@ ANY num_sync ( ) attempt to inline functions and - operators. Inlining initially takes time, but can improve execution - speed. It is unlikely to be beneficial to set - jit_inline_above_cost below - jit_optimize_above_cost. + Sets the query cost above which JIT compilation attempts to inline + functions and operators. Inlining adds planning time, but can + improve execution speed. It is not meaningful to set this to less + than jit_above_cost. + Setting this to -1 disables inlining. + The default is 500000. + + + + + jit_optimize_above_cost (floating point) + + jit_optimize_above_cost configuration parameter + + + + + Sets the query cost above which JIT compilation applies expensive + optimizations. Such optimization adds planning time, but can improve + execution speed. It is not meaningful to set this to less + than jit_above_cost, and it is unlikely to be + beneficial to set it to more + than jit_inline_above_cost. + Setting this to -1 disables expensive optimizations. The default is 500000. @@ -4500,10 +4500,9 @@ SELECT * FROM parent WHERE key = 2400; - Determines whether JIT may be used by + Determines whether JIT compilation may be used by PostgreSQL, if available (see ). - The default is on. @@ -7582,16 +7581,17 @@ SET XML OPTION { DOCUMENT | CONTENT }; - Determines which JIT provider (see ) is - used. The built-in default is llvmjit. + This variable is the name of the JIT provider library to be used + (see ). + The default is llvmjit. + This parameter can only be set at server start. + - If set to a non-existent library JIT will not be + If set to a non-existent library, JIT will not be available, but no error will be raised. This allows JIT support to be installed separately from the main PostgreSQL package. - - This parameter can only be set at server start. @@ -8886,9 +8886,8 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) If LLVM has the required functionality, register generated functions with GDB. This makes debugging easier. - - The default setting is off, and can only be set at - server start. + The default setting is off. + This parameter can only be set at server start. @@ -8904,9 +8903,8 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) Writes the generated LLVM IR out to the file system, inside . This is only useful for working on the internals of the JIT implementation. - - The default setting is off, and it can only be - changed by a superuser. + The default setting is off. + This parameter can only be changed by a superuser. @@ -8919,8 +8917,8 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - Determines whether expressions are JIT compiled, subject to costing - decisions (see ). The default is + Determines whether expressions are JIT compiled, when JIT compilation + is activated (see ). The default is on. @@ -8934,13 +8932,12 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - If LLVM has the required functionality, emit required data to allow + If LLVM has the required functionality, emit the data needed to allow perf to profile functions generated by JIT. This writes out files to $HOME/.debug/jit/; the user is responsible for performing cleanup when desired. - - The default setting is off, and can only be set at - server start. + The default setting is off. + This parameter can only be set at server start. @@ -8953,9 +8950,9 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - Determines whether tuple deforming is JIT compiled, subject to costing - decisions (see ). The default is - on. + Determines whether tuple deforming is JIT compiled, when JIT + compilation is activated (see ). + The default is on. diff --git a/doc/src/sgml/jit.sgml b/doc/src/sgml/jit.sgml index 61cfd59473..8387a4f6be 100644 --- a/doc/src/sgml/jit.sgml +++ b/doc/src/sgml/jit.sgml @@ -21,22 +21,22 @@ What is <acronym>JIT</acronym> compilation? - Just-in-time compilation (JIT) is the process of turning + Just-in-Time (JIT) compilation is the process of turning some form of interpreted program evaluation into a native program, and doing so at run time. - - For example, instead of using a facility that can evaluate arbitrary SQL - expressions to evaluate an SQL predicate like WHERE a.col = - 3, it is possible to generate a function than can be natively - executed by the CPU that just handles that expression, yielding a speedup. + For example, instead of using general-purpose code that can evaluate + arbitrary SQL expressions to evaluate a particular SQL predicate + like WHERE a.col = 3, it is possible to generate a + function that is specific to that expression and can be natively executed + by the CPU, yielding a speedup. PostgreSQL has builtin support to perform JIT compilation using LLVM when - PostgreSQL was built with - --with-llvm (see ). + PostgreSQL is built with + --with-llvm. @@ -64,33 +64,32 @@ + + Inlining + + PostgreSQL is very extensible and allows new + data types, functions, operators and other database objects to be defined; + see . In fact the built-in objects are implemented + using nearly the same mechanisms. This extensibility implies some + overhead, for example due to function calls (see ). + To reduce that overhead, JIT compilation can inline the + bodies of small functions into the expressions using them. That allows a + significant percentage of the overhead to be optimized away. + + + Optimization LLVM has support for optimizing generated code. Some of the optimizations are cheap enough to be performed whenever JIT is used, while others are only beneficial for - longer running queries. - + longer-running queries. See for more details about optimizations. - - Inlining - - PostgreSQL is very extensible and allows new - data types, functions, operators and other database objects to be defined; - see . In fact the built-in ones are implemented - using nearly the same mechanisms. This extensibility implies some - overhead, for example due to function calls (see ). - To reduce that overhead JIT compilation can inline the - body for small functions into the expression using them. That allows a - significant percentage of the overhead to be optimized away. - - - @@ -98,50 +97,46 @@ JIT 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 JIT compilation will often be higher than the time it can save. - To determine whether JIT compilation is used, the total - cost of a query (see and ) is used. - - - - The cost of the query will be compared with the setting of JIT compilation should be used, + the total estimated cost of a query (see + and + ) is used. + The estimated cost of the query will be compared with the setting of . If the cost is higher, JIT compilation will be performed. - - - - If the planner, based on the above criterion, decided that - JIT compilation is beneficial, two further decisions are - made. Firstly, if the query is more costly than the setting of , short + functions and operators used in the query will be inlined. + Secondly, if the estimated cost is more than the setting of , expensive optimizations are - used to improve the generated code. Secondly, if the query is more costly - than the setting of , short functions - and operators used in the query will be inlined. Both of these operations - increase the JIT overhead, but can reduce query - execution time considerably. + applied to improve the generated code. + Each of these options increases the JIT compilation + overhead, but can reduce query execution time considerably. - This cost based decision will be made at plan time, not execution - time. This means that when prepared statements are in use, and the generic - plan is used (see ), the values of the - configuration parameters set at prepare time take effect, not the settings at execution time. + These cost-based decisions will be made at plan time, not execution + time. This means that when prepared statements are in use, and a generic + plan is used (see ), the values of the + configuration parameters in effect at prepare time control the decisions, + not the settings at execution time. - If is set to off, or no + If is set to off, or if no JIT implementation is available (for example because the server was compiled without --with-llvm), - JIT will not be performed, even if considered to be + JIT will not be performed, even if it would be beneficial based on the above criteria. Setting - to off takes effect both at plan and at execution time. + to off has effects at both plan and execution time. @@ -160,9 +155,9 @@ (4 rows) Given the cost of the plan, it is entirely reasonable that no - JIT was used, the cost of JIT would - have been bigger than the savings. Adjusting the cost limits will lead to - JIT use: + JIT was used; the cost of JIT would + have been bigger than the potential savings. Adjusting the cost limits + will lead to JIT use: =# SET jit_above_cost = 10; SET @@ -184,9 +179,9 @@ SET As visible here, JIT was used, but inlining and expensive optimization were not. If , were lowered, just like , that would change. + linkend="guc-jit-inline-above-cost"/> or were also lowered, + that would change. @@ -194,58 +189,53 @@ SET Configuration + The configuration variable determines whether JIT compilation is enabled or disabled. - - - - As explained in the configuration variables + If it is enabled, the configuration variables , , decide whether JIT - compilation is performed for a query, and how much effort is spent doing - so. - - - - For development and debugging purposes a few additional configuration parameters exist. allows the generated bitcode to be - inspected. allows GDB to see - generated functions. emits - information so the perf profiler can interpret - JIT generated functions sensibly. + linkend="guc-jit-inline-above-cost"/>, and determine + whether JIT compilation is performed for a query, + and how much effort is spent doing so. determines which JIT - implementation is used. It rarely is required to be changed. See . + + + For development and debugging purposes a few additional configuration + parameters exist, as described in + . + - + Extensibility Inlining Support for Extensions PostgreSQL's JIT - implementation can inline the implementation of operators and functions - (of type C and internal). See . To do so for functions in extensions, the - definition of these functions needs to be made available. When using PGXS to build an extension against a server - that has been compiled with LLVM support, the relevant files will be - installed automatically. + implementation can inline the bodies of functions + of types C and internal, as well as + operators based on such functions. To do so for functions in extensions, + the definitions of those functions need to be made available. + When using PGXS to build an extension + against a server that has been compiled with LLVM JIT support, the + relevant files will be built and installed automatically. The relevant files have to be installed into $pkglibdir/bitcode/$extension/ and a summary of them - to $pkglibdir/bitcode/$extension.index.bc, where + into $pkglibdir/bitcode/$extension.index.bc, where $pkglibdir is the directory returned by pg_config --pkglibdir and $extension - the base name of the extension's shared library. + is the base name of the extension's shared library. @@ -258,14 +248,16 @@ SET - Pluggable <acronym>JIT</acronym> Provider + Pluggable <acronym>JIT</acronym> Providers PostgreSQL provides a JIT implementation based on LLVM. The interface to the JIT provider is pluggable and the provider can be - changed without recompiling. The provider is chosen via the setting . + changed without recompiling (although currently, the build process only + provides inlining support data for LLVM). + The active provider is chosen via the setting + . @@ -275,10 +267,10 @@ SET named shared library. The normal library search path is used to locate the library. To provide the required JIT provider callbacks and to indicate that the library is actually a - JIT provider it needs to provide a function named + JIT provider, it needs to provide a C function named _PG_jit_provider_init. This function is passed a struct that needs to be filled with the callback function pointers for - individual actions. + individual actions: struct JitProviderCallbacks { @@ -286,6 +278,7 @@ struct JitProviderCallbacks JitProviderReleaseContextCB release_context; JitProviderCompileExprCB compile_expr; }; + extern void _PG_jit_provider_init(JitProviderCallbacks *cb); diff --git a/doc/src/sgml/release-11.sgml b/doc/src/sgml/release-11.sgml index 684d34c091..430573aa17 100644 --- a/doc/src/sgml/release-11.sgml +++ b/doc/src/sgml/release-11.sgml @@ -85,8 +85,8 @@ - JIT compilation of some SQL code, including support for fast evaluation - of expressions + Optional Just-in-Time (JIT) compilation of some SQL code, including + support for fast evaluation of expressions @@ -1076,10 +1076,16 @@ same commits as above --> - Add Just-In-Time + Add Just-in-Time (JIT) compilation of some parts of query plans to improve execution speed (Andres Freund) + + + This feature requires LLVM to be + available, and it is not currently enabled by default, even in + builds that support it. + diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c index c1703094db..7d3883d3bf 100644 --- a/src/backend/jit/jit.c +++ b/src/backend/jit/jit.c @@ -33,7 +33,7 @@ /* GUCs */ bool jit_enabled = true; -char *jit_provider = "llvmjit"; +char *jit_provider = NULL; bool jit_debugging_support = false; bool jit_dump_bitcode = false; bool jit_expressions = true; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 0625eff219..77662aff7f 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -3895,7 +3895,7 @@ static struct config_string ConfigureNamesString[] = }, { - {"jit_provider", PGC_POSTMASTER, FILE_LOCATIONS, + {"jit_provider", PGC_POSTMASTER, CLIENT_CONN_PRELOAD, gettext_noop("JIT provider to use."), NULL, GUC_SUPERUSER_ONLY diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 7486d20a34..4e61bc6521 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -320,11 +320,12 @@ #parallel_setup_cost = 1000.0 # same scale as above #jit_above_cost = 100000 # perform JIT compilation if available - # and query more expensive, -1 disables -#jit_optimize_above_cost = 500000 # optimize JITed functions if query is - # more expensive, -1 disables -#jit_inline_above_cost = 500000 # attempt to inline operators and - # functions if query is more expensive, + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; # -1 disables #min_parallel_table_scan_size = 8MB @@ -350,6 +351,7 @@ #join_collapse_limit = 8 # 1 disables collapsing of explicit # JOIN clauses #force_parallel_mode = off +#jit = on # allow JIT compilation #plan_cache_mode = auto # auto, force_generic_plan or # force_custom_plan @@ -616,13 +618,12 @@ #shared_preload_libraries = '' # (change requires restart) #local_preload_libraries = '' #session_preload_libraries = '' +#jit_provider = 'llvmjit' # JIT library to use # - Other Defaults - #dynamic_library_path = '$libdir' -#jit = on # allow JIT compilation -#jit_provider = 'llvmjit' # JIT implementation to use #------------------------------------------------------------------------------ # LOCK MANAGEMENT