32.1. Что такое JIT-компиляция? #
JIT-компиляция (Just-In-Time compilation, Компиляция «точно в нужное время») — это производимая во время выполнения процедура преобразования интерпретируемого варианта исполнения программы в программу на языке процессора. Например, вместо использования универсального кода, способного вычислять произвольные SQL-выражения, для вычисления конкретного условия WHERE a.col = 3 можно сгенерировать функцию, предназначенную именно для этого выражения, которую сможет выполнять непосредственно процессор, так что она будет выполняться быстрее.
В Postgres Pro поддержка JIT-компиляции с использованием LLVM включается при сборке Postgres Pro с ключом --with-llvm.
32.1.1. Операции, ускоряемые с применением JIT #
В настоящее время реализация JIT в Postgres Pro поддерживает ускорение вычисления выражений и преобразования кортежей. В будущем могут быть ускорены и некоторые другие операции.
Вычисление выражений производится при обработке предложений WHERE, целевых списков, агрегатов и проекций. Оно может быть ускорено в результате генерирования кода, предназначенного для каждого конкретного случая.
Преобразование кортежей — процедура перевода кортежа с диска (см. Подраздел 74.6.1) в развёрнутое представление в памяти. Его можно ускорить, создав функции, предназначенные для определённой структуры таблицы и количества извлекаемых столбцов.
32.1.2. Встраивание #
СУБД Postgres Pro очень гибка и позволяет определять новые типы данных, функции, операторы и другие объекты базы данных; см. Главу 41. В действительности встроенные объекты реализуются практически теми же механизмами. С этой гибкостью связаны некоторые издержки, например, сопутствующие вызовам функций (см. Раздел 41.3). Для сокращения этих издержек JIT-компиляция может встраивать тела маленьких функций в код выражений, использующих их. Это позволяет соптимизировать значительный процент подобных издержек.
32.1.3. Оптимизация #
В LLVM поддерживается оптимизация сгенерированного кода. Некоторые оптимизации обходятся достаточно дёшево и могут выполняться при использовании JIT в любом случае, тогда как другие оправданы только при длительных запросах. Подробнее об оптимизации рассказывается в https://llvm.org/docs/Passes.html#transform-passes.
32.1. What Is JIT compilation? #
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 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.
Postgres Pro has builtin support to perform JIT compilation using LLVM when Postgres Pro is built with --with-llvm.
32.1.1. JIT Accelerated Operations #
Currently Postgres Pro's JIT implementation has support for accelerating expression evaluation and tuple deforming. Several other operations could be accelerated in the future.
Expression evaluation is used to evaluate WHERE clauses, target lists, aggregates and projections. It can be accelerated by generating code specific to each case.
Tuple deforming is the process of transforming an on-disk tuple (see Section 74.6.1) into its in-memory representation. It can be accelerated by creating a function specific to the table layout and the number of columns to be extracted.
32.1.2. Inlining #
Postgres Pro is very extensible and allows new data types, functions, operators and other database objects to be defined; see Chapter 41. 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 Section 41.3). 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.
32.1.3. 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. See https://llvm.org/docs/Passes.html#transform-passes for more details about optimizations.