PostgreSQL JIT编译

@[TOC](PostgreSQL Just-in-Time Compilation(JIT))

什么是just-in-time,在PostgreSQL里怎么配置。

What is JIT compilation?

Just-in-Time (JIT)编译是在运行时把解释型程序转换成原生程序的过程。例如,不使用可以评估任意SQL的通用代码来评估特定的谓词(比如WHERE a.col),而是生成一个特定的,能被CPU原生执行的该表达式的函数,来加速。
当构建PostgreSQL的时候使用了 --with-llvm选项,PostgreSQL使用LLVM 1支持JIT编译。
更多细节请参考 src/backend/jit/README。

JIT Accelerated Operations

现在,PostgreSQL的JIT实现已经支持加速表达式评估和tuple deforming。未来将支持更多算法。
表达式评估用来评估WHERE clauses、target lists、aggregates和projections。每种情况下都可以生成代码提高速度。
Tuple deforming是把磁盘元组(tuple)转换成内存表示的过程。它根据table layout和被提取的列的数量生成函数来加速。

Inlining

PostgreSQL的扩展性非常好,且允许新的数据类型、函数、运算符和其他数据库对象。事实上,内建的对象也是使用类似的机制实现的。这种扩展性意味着一些开销,例如由于函数调用。为了减少这些开销,JIT编译器在表达式中内联小函数体。这样可以优化相当多的开销。

Optimization

LLVM支持优化生成的代码。一些优化是足够廉价的,只要开启了JIT就会执行,而其他的只有在慢查询时才有利。优化的细节请见transform-passes

When to JIT?

JIT编译主要在长时间运行的CPU密集的查询时有利。通常,这些都是分析性的查询。对于短查询,执行JIT编译的开销经常高于它能节省的时间。
使用一个查询的总的评估代价(total estimated cost),决定是否使用JIT编译。查询的评估代价和jit_above_cost配置做比较。如果代价高,就执行JIT编译。还需要做出另外两个决定。首先,如果评估代价大于jit_inline_above_cost的设置,查询中的短函数和运算符将是内联的。其次,如果评估代价大于jit_optimize_above_cost的设置,就使用昂贵的代价改进生成的代码。这些选项都增加了JIT编译的开销,但是减少了查询执行时间。
这些基于代价的决定,会在计划时间(plan time)执行,而不是在执行时间。这意味着当使用PrepareStatement的时候,执行一个通用的计划。配置参数的值在准备时间(prepare time)控制决定。

注意:如果关闭jit,或者如果JIT编译无效(例如因为服务器没使用–with-llvm选项编译)。JIT将不会执行,甚至在根据上面的规则判断有利的情况下也不执行。关闭jit会影响计划和执行时间。

使用EXPLAIN,可以知道是否使用了JIT。下面的例子,就没有使用JIT:

=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class;
QUERY PLAN
--------------------------------------------------------------------------------
Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1)
    -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4)
    (actual time=0.017..0.111 rows=356 loops=1)
    Planning Time: 0.116 ms
    Execution Time: 0.365 ms
    (4 rows)

考虑到计划的代价,不使用JIT是完全合理的;JIT的代价大于潜在的节省。调整代价限制将导致JIT的使用:

=# SET jit_above_cost = 10;
SET
=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class;
QUERY PLAN
--------------------------------------------------------------------------------
Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1)
    -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4)
    (actual time=0.019..0.052 rows=356 loops=1)
    Planning Time: 0.133 ms
    JIT:
        Functions: 3
        Options: Inlining false, Optimization false, Expressions true,
        Deforming true
        Timing: Generation 1.259 ms, Inlining 0.000 ms, Optimization 0.797 ms, Emission 5.048 ms, Total 7.104 ms
    Execution Time: 7.416 ms

上面的例子使用了JIT,但是,没做内联和昂贵的优化。如果jit_inline_above_cost或者jit_optimize_above_cost也设置得小一些,就会执行。

Configuration

配置变量jit决定打开还是关闭JIT编译。如果打开jit,配置变量jit_above_cost、jit_inline_above_cost和jit_optimize_above_cost,决定某查询是否执行JIT编译,以及花费的代价是多少。jit_provider决定使用哪个JIT编译,它一般不需要修改。
此外,还有一些开发和调试目的的附加配置参数,见19.17。

Extensibility

Inlining Support for Extensions

PostgreSQL的JIT编译能内联C函数或内部函数的函数体,就像操作符基于的那些函数。函数要实现这样的扩展,那些函数的定义需要有效。当使用PGXS在支持JIT的服务器build一个扩展,相应的文件将被build并且自动安装。
相应的文件将被安装到 p k g l i b d i r / b i t c o d e / pkglibdir/bitcode/ pkglibdir/bitcode/extension/,他们的摘要也被安装到 p k g l i b d i r / b i t c o d e / pkglibdir/bitcode/ pkglibdir/bitcode/extension。
p k g l i b d i r 是 由 p g c o n f i g − − p k g l i b d i r 返 回 的 目 录 , pkglibdir是由pg_config --pkglibdir返回的目录, pkglibdirpgconfigpkglibdirextension是扩展的共享库的基本名(base name)。

注意:对于PostgreSQL内置的函数,bitcode将被安装在$pkglibdir/bitcode/postgres。

Pluggable JIT Providers

PostgreSQL提供了基于LLVM的JIT编译。JIT提供者的接口是可插拔的,不用重新编译就可以修改提供者(但是,目前build过程只提供LLVM的内联支持)。设置jit_provider可选择实际的提供者。

JIT Provider Interface

JIT提供者通过可动态加载的共享库加载。通过通用的库搜索路径定位库。为了提供需要的JIT提供者回调,为了表明该库是实际上的JIT提供者,需要有一个C函数名PG_jit_provider_init。该函数传递一个struct,其中包括每个动作的回调函数指针:

struct JitProviderCallbacks {
    JitProviderResetAfterErrorCB reset_after_error;
    JitProviderReleaseContextCB release_context;
    JitProviderCompileExprCB compile_expr;
};

extern void _PG_jit_provider_init(JitProviderCallbacks *cb);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值