使用SIMD指令校验UTF-8

翻看postgresql email list,发现有对SIMD指令应用到PG的讨论,很有价值。记录下来以作分析使用。

从 b80e10638e3开始,有一个用于校验字符串编码的新API,使得我们有更多算法选择。对于UTF-8来说,已证明在解码[1]和校验[2]方面,使用SIMD比标准方法快得多。出于多方面原因,从UTF-8的ascii子集开始是有意义的。首先,ascii在数据库内容中非常普遍,尤其是在批量加载中。其次,ascii可以使用任何x64-64芯片使用简单的SSE2内在函数进行严重,我猜我们可以在编译时检测到,而不会与运行时检测混淆。使用SSE的通用案例比较复杂并且涉及SSE4.2或AVX。

这是我电脑上的一些数字。测试和Heikki的[3]一样,但我添加了一个案例,包含95%的汉字,只是为了展示与混合ascii/多字节案例对比情况。

master:

 chinese | mixed | ascii

---------+-------+-------

1081 |   761 |   366

patch:

 chinese | mixed | ascii

---------+-------+-------

1103 |   498 |    51

纯ascii情况下的加速效果还是很不错的。

在随附的POC中,仅有一个形式上可以移植的案例,完整性的以后再用。快速路径内联在pg_utf8_verifystr()中。ascii快速路径可以抽象成一个单独函数,该函数传递一个函数指针用于进行完整的编码验证。这将允许具有严格的ascii子集的其他编码也可以使用它。但对这种抽象进行编码可能有点混乱,并且b80e10638e3已经比PG13有更好性能了。

我还尝试使用DFA进行完整的UTF-8识别,但到目前位置,这只能使性能更糟。如果我在这方面取得成功,我会将其添加到Patch中。

[1] https://woboq.com/blog/utf-8-processing-using-simd.html

[2]

​https://lemire.me/blog/2020/10/20/ridiculously-fast-unicode-utf-8-validation/​

[3]

​https://www.postgresql.org/message-id/06d45421-61b8-86dd-e765-f1ce527a5a2f@iki.fi​

Attachment

Content-Type

Size

v1-verify-utf8-sse-ascii.patch

application/x-patch

2.3 KB

原文

​https://www.postgresql.org/message-id/CAFBsxsEV_SzH%2BOLyCiyon%3DiwggSyMh_eF6A3LU2tiWf3Cy2ZQg%40mail.gmail.com​