AMD与Intel:Unicode性能基准测试
通俗来说,我们的处理器分为两种类型:手机中的ARM处理器和Intel与AMD制造的x64处理器。最好的服务器处理器过去由Intel制造。但如今,Intel越来越难以跟上竞争步伐。
最近,亚马逊提供了最新的AMD微架构(Zen 5)。具体来说,如果您启动一个r8a实例,您将获得AMD EPYC 9R45处理器。对应的Intel实例(r8i)则配备Intel Xeon 6975P-C处理器。这款Intel处理器属于Granite Rapids家族(2024年)。
Phoronix的Michael Larabel有几篇关于新AMD处理器的文章。其中一篇题为《AMD EPYC 9005带来惊人性能》。这篇文章非常值得一读。他发现,与之前的AMD处理器(采用Zen 4微架构)相比,AMD EPYC 9R45速度快了1.6倍。在第二篇文章中,Michael将AMD处理器与相应的Intel处理器进行了比较。他发现AMD处理器比Intel处理器快1.6倍。
我决定亲自测试一下。我正好在准备simdutf库的新版本发布。simdutf库支持UTF-8、UTF-16和UTF-32编码之间的快速转码,以及其他功能。它被主要浏览器和JavaScript运行时(如Node.js或Bun)使用。一个常见且重要的操作是从UTF-16到UTF-8的转换。JavaScript内部使用UTF-16,因此大多数字符使用2字节,而互联网默认使用UTF-8,字符可以使用1到4字节。
UTF-16是一种可变长度Unicode编码,使用单个16位代码单元(值从0x0000到0xd7ff和0xe000到0xffff)表示大多数常见字符,但通过使用代理对扩展到U+FFFF以上的完整Unicode范围:一个高代理(0xd800到0xdbff)后跟一个低代理(0xdc00到0xdfff),共同编码一个单个补充字符,映射到四个UTF-8字节。因此,我们可以认为代理对中的每个元素在UTF-8中占两个字节。范围0x0000到0x007f(ASCII)的非代理代码单元变为一个字节,0x0080到0x07ff变为两个字节,0x0800到0xffff(不包括代理)变为三个字节。
我的基准测试代码首先确定需要多少输出内存,然后进行转码。
|
|
在最近的处理器上,转码代码并不简单(Clausecker和Lemire,2023)。然而,从UTF-16数据计算UTF-8长度稍微简单一些。
这些Intel和AMD处理器支持AVX-512指令:这些指令可以操作最多64字节的寄存器,相比我们通常使用的64位寄存器。这是SIMD的一个实例:单指令多数据。使用AVX-512,您可以一次加载和处理32个UTF-16单元。我们的主要例程如下所示。
|
|
代码处理从内存加载的512位UTF-16代码单元向量,使用_mm512_loadu_si512。然后通过首先应用按位AND(_mm512_and_si512)用0xf800掩码每个代码单元,仅保留高五位,并将结果(_mm512_cmpeq_epi16_mask)与0xd800比较;这产生一个32位掩码,其中位为任何在代理范围(0xd800到0xdfff)内的代码单元设置,指示潜在的UTF-16代理对,这些代理对不应在UTF-8中贡献额外长度。接下来,我们使用按位测试检查(_mm512_test_epi16_mask)每个代码单元对0xff80的掩码,为任何非ASCII代码单元在c0中设置位。类似地,另一个_mm512_test_epi16_mask函数对0xf800在c1中为需要3字节UTF-8的代码单元(代理对除外)设置位。最后,代码累积c0和c1中设置位的数量到计数器,然后减去代理掩码的popcount。总体而言,我们可以使用大约十二条指令处理约32个UTF-16单元。(感谢Wojciech Muła的有见地的设计,以及Yagiz Nizipli帮助我进行相关优化。)
配备AMD处理器的大型亚马逊实例价格为0.13892美元/小时,而Intel处理器为0.15976美元/小时。我使用Amazon Linux启动了这两个实例。然后在shell中运行以下命令。
|
|
我得到以下结果。
| 处理器 | GB/s | GHz | 指令/字节 | 指令/周期 |
|---|---|---|---|---|
| AMD | 11 | 4.5 | 1.7 | 4.0 |
| Intel | 6 | 3.9 | 1.7 | 2.6 |
基准测试结果显示,在UTF-16到UTF-8转码中,AMD处理器的吞吐量几乎是Intel处理器的两倍(10.53 GB/s对比5.96 GB/s),部分得益于其更高的运行频率。两个系统都需要相同的每字节1.71指令,但AMD实现了显著更高的每周期指令数(3.98 i/c对比2.64 i/c),展示了在AVX-512流水线中的卓越执行效率。其中一个原因与执行单元的数量有关。AMD处理器有四个能够处理512位寄存器的计算单元,而Intel通常仅限于两个这样的执行单元。
我的基准测试比Larabel的更狭窄,它们有助于显示在使用AVX-512指令时,AMD相对于Intel具有巨大优势。考虑到Intel发明了AVX-512而AMD较晚支持,这一点尤其引人注目。可以说AMD在Intel的游戏中击败了Intel。
我的基准测试代码可用。
进一步阅读:Robert Clausecker, Daniel Lemire, Transcoding Unicode Characters with AVX-512 Instructions, Software: Practice and Experience 53 (12), 2023。