【译】使用英特尔 AVX-512 更快地解析 JSON
原文链接:https://lemire.me/blog/2022/05/25/parsing-json-faster-with-intel-avx-512/
许多最新的英特尔处理器都受益于称为 AVX-512 的新指令系列。这些指令在宽寄存器(最多 512 位)上运行,并遵循单指令多数据 (SIMD) 范例。这些新的 AVX-512 指令允许您打破一些速度记录,例如以内存副本的速度解码base64数据。
大多数现代处理器都有 SIMD 指令。AVX-512 指令更宽(每个寄存器更多位),但这不一定是它们的主要吸引力。如果您只是采用现有的 SIMD 算法并将它们应用于 AVX-512,您可能不会获得您想要的那么多好处。的确,更宽的寄存器是有益的,但在超标量处理器(每个周期可以发出多条指令的处理器)中,每个周期可以发出的指令数量同样重要。通常地,处理器每个周期可以发出的 512 位 AVX-512 的指令更少,因此这些指令更耗费资源。要想真正充分利用 AVX-512,开发者需要仔细设计代码,而与此同时英特尔还在不断增加新的指令。总的说,AVX-512 不是单个技术,而是一个系列指令集。
此外,AVX-512 指令的早期实现通常会导致可测量的降频:处理器会在使用这些指令后一段时间内降低其频率。值得庆幸的是,支持 AVX-512(Rocket Lake 和 Ice Lake)的最新英特尔处理器已经取消了这种系统的频率限制。值得庆幸的是,在运行时很容易检测到这些最新的处理器。
几年前,我们发布了一个名为 simdjson 的非常快速的 C++ JSON 解析器。它作为解析器有些独特,因为它严重依赖 SIMD 指令。在几个指标上,它曾经是并且仍然是最快的 JSON 解析器,尽管已经出现了其他有趣的竞争对手。
最初,我为 simdjson 编写了一个快速而肮脏的 AVX-512 内核。我们从未合并它,一段时间后,我只是将其删除。然后我就忘记了。
感谢有才华的英特尔工程师(Fangzheng Zhang 和 Weiqiang Wan)的贡献,以及本博客读者(Kim Walisch 和 Jatin Bhateja)的间接贡献,我们制作了一个新的 AVX-512 内核。与往常一样,simdjson 是许多人的工作,是一个由数十名贡献者组成的整个社区。我必须对第一次写信给我关于 AVX-512 端口的张方正表示感谢。
我们刚刚发布了最新版本的 simdjson。它打破了新的速度记录。
考虑一个有趣的测试,您试图扫描整个文件(跨越千字节)以找到与某个标识符对应的值。在simdjson中,代码如下:
1 | auto doc = parser.iterate(json); |
在带有 GCC 11 的 Tiger Lake 处理器上,处理速度提高了 60%,以每秒处理的输入字节数表示。
simdjson (512-bit SIMD): new | 7.4 GB/s |
---|---|
simdjson (256-bit SIMD): old | 4.6 GB/s |
速度增益非常重要,因为在这个任务中,我们大多只是读取数据,而我们做的二次处理相对较少。我们不会从 JSON 数据中创建树,也不会创建数据结构。
simdjson 库有一个缩小功能,它只是从输入中去除不必要的空格。也许令人惊讶的是,我们的速度是之前基线的两倍多:
simdjson (512-bit SIMD): new | 12 GB/s |
---|---|
simdjson (256-bit SIMD): old | 4.3 GB/s |
另一个合理的基准是将输入完全解析为具有完全验证的 DOM 树。解析标准 JSON 文件 ( twitter.json
),我获得了近 30% 的收益:
simdjson (512-bit SIMD): new | 3.6 GB/s |
---|---|
simdjson (256-bit SIMD): old | 2.8 GB/s |
虽然 30% 听起来可能并不令人兴奋,但我们是从一个快速的基线开始的。
我们能做得更好吗?肯定的。有许多我们尚未使用的 AVX-512 指令。我们不使用三元布尔运算 ( vpternlog
)。我们没有使用新的强大的 shuffle 函数(例如,vpermt2b
)。我们有一个共同进化的例子:更好的硬件需要新的软件,这反过来又使硬件大放异彩。
当然,要获得这些新优势,您需要具有足够 AVX-512 支持的最新 Intel 处理器,显然,您还需要相对较新的 C++ 处理器。最近的一些笔记本电脑级英特尔处理器不支持 AVX-512,但如果您依赖 AWS 并拥有大型英特尔节点,您应该没问题。
您可以直接获取我们的版本或等待它到达标准包管理器之一(MSYS2、conan、vcpkg、brew、debian、FreeBSD 等)。