Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
bzhaoopenstack opened this issue Dec 23, 2020 · 0 comments
Open

Comments

@bzhaoopenstack
Copy link
Collaborator

bzhaoopenstack commented Dec 23, 2020

作者: 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是否能独闯一片天地,现在的趋势说明了一切,对于鲲鹏来说,我觉得是非常好的势头,让我们拭目以待吧。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant