kunpengcompute / kunpengcompute.github.io

Kunpeng Tech Blog: https://kunpengcompute.github.io/
Apache License 2.0
17 stars 5 forks source link

号外号外,MDB认可了Huawei在社区上游的性能优化 #73

Open bzhaoopenstack opened 3 years ago

bzhaoopenstack commented 3 years ago

作者: bzhaoopenstack

2020年是非常令人难忘的一年,2020年是我们包含的无数个首次,居家隔离,在家办公,千辛万苦从老家赶往单位上班,从艰难的上班路程一直到现在越来越趋于正常的环境。回想这一整年,我们从今年年后开始组建团队在社区上游进行鲲鹏优化相关的工作,一开始我们只有两个人,到现在的初具规模,伙伴们从一个ARM优化小白成长到能够独挡一面的先驱者,这一年的经历相信会在我们的人生当中留下浓重的一笔。


就在昨天,通过组内的不懈努力,我们在MariaDB开源社区上游获得社区官方的认可,团队中的大佬Krunal Bauskar榜上有名,同时还有来自ARM公司的Gu Yuqi和AWS的Tsahi Zidenberg。这是社区对我们的承认,感谢社区,期望我们今后能够为越来越多的幕后英雄鼓掌。

我们浏览一下来自MariaDB Foundation的Vicențiu Ciorbaru信中描述的,原文参见这里:

在2020年, 各行各业有很多ARM架构的声音。对于MariaDB来说,情况也是一样的。首先,在今年,我们已经扩展了测试基础架构,用以在ARM上的覆盖更多Linux发行版(Debian,Ubuntu,Fedora,CentOS,RedHat),我们正在为所有这些Linux发行版构建MariaDB软件包。除了现有的RPM和DEB包之外,下一个MariaDB发行版的tar包还将包括可在ARM上运行的二进制文件。

所有的这些都离不开华为的帮助,华为已经给我们捐赠几台ARM构建机器用于扩展测试基础架构来满足这项工作的需求。我们坚信,只有通过在尽可能多平台上进行测试,使用尽可能多的编译器,我们才能保证MariaDB的高性能和稳定性。旁注,社区仍然缺少SPARC硬件,如果您碰巧有可用的硬件,请告诉我们。

此外,我们还要感谢Krunal Bauskar, Gu YuqiTsahi Zidenberg为我们增强了ARM的性能和相关错误的修复。

为了获得最佳性能,编写代码时应考虑到底层硬件。这就是为什么性能关键代码尽可能使用本机指令的原因。这种情况就是计算crc32c校验和,由Gu Yuqi通过PR 772贡献。Krunal在此工作上引入了PR 1558,其中统一了crc32库,并尽可能使用SIMD(单指令,多数据)包装器来确保运行高效。此外,某些任务,如检测代码或计时相关的函数调用,需要非常精确的计时器。通过添加本机ARM代码,my_timer_cycles()引入了精确的硬件计时器。这是通过PR 1620实现的,与此同时还能通过编译器标志来改进原子操作性能。

我们感谢社区参与确保MariaDB利用所有可用的硬件功能,我们期待获得更多!

谢谢!

相当振奋啊,不过我们的文风不应该是纯粹的吹捧,干货还是要的。下面我们分析一下,信中提及的MariaDB在ARM上的硬件优化。

PR 772这个PR比较好的阐释了如何将一个底层硬件功能开放到上层软件,代码结构非常清晰。从crc32.cmake自适应底层架构进行分支选择,使用ARM v8加密指令优化crc32c计算密集型任务,放弃使用原本的线性crc指令,提升CPU的稳定性。引入了新的extension, 位置在extra/crc32_armv8_neon/crc32_armv8.c,都是底层汇编的适配。x86使用的是crc32b和crc32q汇编指令完成CRC32C校验值计算功能,而Arm64平台使用crc32cb、crc32ch、crc32cw、crc32cx 4个汇编指令完成CRC32C校验值计算功能。

指令 输入数据位宽(bit) 备注
crc32cb 8 适用输入数据位宽为8bit,可用于替换x86的crc32b汇编指令。
crc32ch 16 适用输入数据位宽为16bit。
crc32cw 32 适用输入数据位宽为32bit。
crc32cx 64 适用输入数据位宽为64bit,可用于替换x86的crc32q汇编指令。

更多的请参考官方文档,或者这里

PR 1558这个PR是基于PR 772进行的改进,引入位于mysys/checksum.c的上层接口,用于计算表和binlog校验和。并对powerpc,X86和ARM平台都进行了优化,X86使用的是PCLMUL指令,ARM使用ACLE调用底层指令替代了默认的zlib-crc32。同时对相关checksum使用的调用进行了规整,梳理出了对应所有硬件平台的内部上层接口,包含x86, ARM, POWERPC等等硬件平台,使其尽量使用底层硬件加速,避免回退到zlib crc32软实现。回看这里,对于ARM,亮点不但是使用了底层加速,还是基于SIMD思想的。那么,

What is SIMD?

通常我们进行多媒体处理的时候,很多的数据都是16位或者8位的,如果这些程序运行在32位的机器上,那么计算机有一部分的计算单元是没有工作的.所以这是一种浪费.为了更好的使用那些被浪费的资源.SIMD就应运而生了.SIMD这种技术就是使用一条指令,但对多个相同类型和尺寸的数据进行并行处理.就像我们现实生活中的好几个人都在做同一件事情那样,这样就可以将速度提升很多倍.

这个PR干了啥?看extra/crc32_armv8_neon/crc32_armv8.c

/* There are multiple approaches to calculate crc.
Approach-1: Process 8 bytes then 4 bytes then 2 bytes and then 1 bytes
Approach-2: Process 8 bytes and remaining workload using 1 bytes
Apporach-3: Process 64 bytes at once by issuing 8 crc call and remaining
            using 8/1 combination.
Based on micro-benchmark testing we found that Approach-2 works best especially
given small chunk of variable data. */

充分测试后,上述第二种的性能最高,特别是在小块数据的场景中,好底层啊,算法和原理参考这里,同时测出来的数据就是这么表现的。看着其实就是运算时合理利用闲置的硬件资源,尽量保证使用更多的硬件,ARM的有效性体现的淋漓尽致,估计后面的优化工作会有大量相关的代码优化。

然后,我抱着试试看的态度,将这两个PR进行了测试,结果还是比较喜人的。

without patch
mysql> checksum table test.sbtest1;
+--------------+------------+
| Table | Checksum |
+--------------+------------+
| test.sbtest1 | 3664919850 |
+--------------+------------+
1 row in set (15.06 sec)

mysql> checksum table test.sbtest2;
+--------------+------------+
| Table | Checksum |
+--------------+------------+
| test.sbtest2 | 2870489758 |
+--------------+------------+
1 row in set (15.07 sec)

with patch
-----------------
mysql> checksum table test.sbtest1;
+--------------+------------+
| Table | Checksum |
+--------------+------------+
| test.sbtest1 | 3664919850 |
+--------------+------------+
1 row in set (7.35 sec)

mysql> checksum table test.sbtest2;
+--------------+------------+
| Table | Checksum |
+--------------+------------+
| test.sbtest2 | 2870489758 |
+--------------+------------+
1 row in set (7.41 sec)

你发现了什么?我们发现了合入后checksum时间由15秒降到了7.4秒,近50%性能提升!

PR 1620引入了两个东西,一个是引入了gcc -moutline-atomics能让应用自定义原子操作,另外将硬件时钟引入到mysql/innodb自己的时钟周期,这样,让程序代码执行时间的衡量可以精确到CPU Cycle级别,是不是有种合二为一的感觉。其实这类具体的做法比较早的就有人发出来了,可以参考这里,这一点说明软件可以更贴近硬件来做优化。

总的来说,硬件适配及底层硬件功能应用在ARM上也才刚刚起步,尤其是在开源社区上游,我们要做的工作还有很多,但是目前来看,ARM的潮流已经来了,苹果的M1,以及最近微软宣称自己也要开始研发自己的ARM芯片,这说明ARM的圈子慢慢变大,从最开始的ARM,到ARM + 华为 + AWS,到现在广大的群体。其实作为云厂商的AWS给我们上了非常重要的一课,排老大到底是有原因的,作为未来厂商的发展,一定是软硬结合的这种结构,所以软件生态牵引硬件这种模式应该会持续很久。

好了,ARM是否能独闯一片天地,现在的趋势说明了一切,对于鲲鹏来说,我觉得是非常好的势头,让我们拭目以待吧。