自动秒收录

技术分享可以讲哪些啊 (技术分享)


文章编号:827 / 更新时间:2023-11-08 19:18:44 / 浏览:
技术分享



2023年8月23日,阿里云弹性计算团队与智东西公开课联合出品的系列课程【阿里云弹性计算技术公开课】最后一节正式收官,阿里云弹性计算架构师张伟带来了主题为《软件跨架构迁移(x86->ARM)的原理及实践》的课程分享,本期课程在阿里云官网、智东西官网、钉钉视频号、阿里云微信视频号、阿里云开发者微信视频号、阿里云创新中心直播平台&视频号等多平台同步播出。

针对阿里云倚天实例的软件迁移,阿里云为开发者提供了迁移工具EasyYiTian和性能调优工具KeenTune,能够帮助用户解决软件迁移评估分析过程中人工分析投入大、准确率低、代码兼容性人工排查困难、迁移经验欠缺、反复依赖编译调错定位等痛点,实现业务在ECS倚天ARM实例的快速适配。EasyYiTian支持主流开发语言,通过系统自动化扫描可以一键生成分析报告。KeenTune通过AI算法与专家知识库的有效结合,为软件应用提供动态和静态协同调优的能力。


以下内容根据张伟的课程整理而成,供大家阅览:



一、软件迁移的原理


大家都知道,X86架构在数据中心场景和个人家用的PC场景是十分常见的芯片架构,而ARM架构是在移动互联网兴起之后,才在低功耗设备上逐步占领了市场。同时,ARM芯片就开始在慢慢布局数据中心的业务了,最近几年也呈现了爆发的趋势。



那么为什么软件从X86架构迁移到ARM架构需要一定的工作量呢?它背后的原因是,这两个芯片的架构在寄存器和指令集的设计上有根本性的差异,主要体现在两个部分:

在通用寄存器的数量上,X86平台上的通用寄存器一般是16个,而ARM上是32个。在这种情况下,当执行上下文切换等操作时,差异就体现出来了。

在指令集的设计上,X86是复杂指令集,即CISC架构;ARM是RISC架构,是精简指令集。很多时候大家也会把功耗归因于指令集设计架构上,X86上的功耗普遍要高一点,ARM上相对低一点。

指令的设计最终也体现在指令集层面,不同指令的设计思维最终体现出来的是不同的指令集。目前X86上使用AVX512指令集,ARM上使用SVE2指令集。这里几乎所有指令的调用方式的逻辑都是有差异的,所以导致了软件在做迁移的时候会带来一定的工作量。

上图简单罗列了一些代表的厂商,X86场景比较有代表性的是Intel和AMD,ARM场景是阿里的平头哥和AMPERE。



寄存器和指令集的差异,最终导致了在软件跨架构迁移的时候需要做一些改变。举个例子,看一下同一段程序代码在X86上编译和在ARM上编译,生成的汇编指令分别是什么。

这个代码是一个比较简单的函数,这里对第三行做了重点的标注,其背后的含义也很简单,即n类的对象,它的局部变量叫x,我们给它赋值为42,在X86上的编译我是通过X64的编译器做的。在X86的平台上,这段代码一般会直接被翻译成一行汇编指令。

这个汇编指令就是把42这个立即数存入rax指向的内存位置中。这个rax是一个通用寄存器,它里面存的是一个内存的地址。DWORD PTR表示操作数是一个双字,这里可以看到一条写寄存器的指令,它隐含了store操作。所谓的store操作是指从寄存器往内存里写,而从内存里把数据读到计算机上,我们称之为load。

在ARM平台上,我们会把这段代码翻译成两行汇编指令。首先我们把立即数42移动到通用寄存器w1中,然后再去做store的操作,也就是把w1寄存器中的值存储到内存地址[x0]中。这里面有两条指令,显示调用store操作。

综上,说明了精简指令集和复杂指令集在一些基础操作上会有一些差异,所以编码、编译都是有相当多的差异性。


二、软件迁移的实施



上图展示的是一个比较常用的步骤,通过这四步一般就能把整个迁移工作做完。

第一步,迁移准备。在真正执行迁移前,我们要先确定场景,并制定策略,包括环境准备。

第二步,执行迁移。最重要的是要做一个编译。

第三步,测试优化。通常就是功能测试和性能测试,这里还包括了黑盒白盒的单元测试,冒烟测试等等。此外,还要考虑性能调优的工作,因为在跨架构迁移中性能是重中之重,比如如何保证软件在X86上跑和在ARM上跑的性能没有变化,甚至更好。

第四步,部署维护。目前云上的部署有很多比较先进、比较快捷的方式,相对于传统的软件部署方式而言,云上的软件部署可以称之为是跨代际的、有革命性的变化。



接下来介绍一下制定迁移的策略,上图是一个比较简单的软件调用栈。

在软件类别方面,我们把软件的框架和软件库一起包进来了。针对软件以及软件调用的框架(软件库),分成了三种方式。

第一种,自研软件,这是业界中比较普遍的方式。

第二种,开源软件,在开源基础上直接使用,或者在开源基础上做一定自研改动。

第三种,商用软件,这个的工作量相对较小。对于商务软件而言,我们可以直接联系软件的供应商,获得支持ARM架构的软件即可。

目前,商用软件基本上都是支持ARM的,在高性能计算和AI场景会稍微特殊一点,因为目前商用的软件对于ARM的支持还处于上升期。通过业界各个公司的努力,目前可以支持大部分的应用、软件的库及软件的框架。但对于大数据、web等互联网场景和大量的一般性场景,ARM架构的渗透率还是非常高的,开源软件就更不必说了。

上图右侧展示了一些常用的软件,它们都适配ARM架构。而自研的软件就要考虑很多因素了,如果是开源的软件,我们可以直接到一些开源的社区或者公共的镜像网站上拉到一些我想要的开发软件。但是对于自研软件,我们需要制定一些策略,自己做一些编译工作。

上图中还展示了一些链接,大家如果需要找一些开源软件,可以通过这些链接来找。比较常用的有阿里开源镜像站,它在国内的影响力还是比较大的。RPM Find是全球大量的程序员习惯找RPM包的地方,如果你用的是debain的Ubuntu上的方式,可以在相应的网上网站上找到。

另外,还有一个开源社区Linaro ,它和ARM合作了很多年,在做ARM整个生态的工作。这个网站上也提供了大量的开发软件,还有一些可能你不容易找到的软件版本。如果出现一些软件性能和功能上的疑难杂症,也可以在Linaro上讨论。

上图最下边有个例子,在阿里的开源镜像站里有一个软件包,我们如何找到支持相应的ARM的版本的呢?这是以make的软件包为例,我们在阿里的镜像源网站用浏览器登录之后,可以看到arm64架构适配的软件包,我们直接点击下载,然后直接安装就可以了。



在介绍完软件的类别之后,下面我们要考虑的是软件类型是编译型软件还是解释型软件。

对于解释型的软件,跨架构迁移的难度会比较小。几个常用的解释型语言包括Java、Python、PHP等,源码由编译器/解释器生成字节码,再由虚拟机解释执行,所以从X86到ARM上几乎不需要做任何迁移的工作。但对于编译型语言,源码需要经过编译、链接等复杂的工作才能变成真正的机器码,因此我们必须要选择合适的编译器才能把它编译好。

右侧是一些推荐的版本,对于解释型语言,虽然编译过程我们可以省略掉,但在性能方面我们还是需要特别注意一下。比如JDK层面,我们推荐大家使用阿里的JDK,比较新的版本Dragonwell 11。对于编译型语言,我们推荐大家使用gcc 10.2.1,LLVM 13,ARM clang 13,以及阿里自研的acc。阿里自研的这个版本里有一些插件可以帮助大家在特定的ARM场景里做到一些性能的优化,推荐大家使用它。Golang版本我们推荐大家使用go 1.18+,因为它的旧版本在ARM上适配的没有新的好。



接下来介绍一下操作系统的选择,以及加速指令集迁移的建议。

目前阿里云的官网实例上主流的操作系统有阿里自研的ALinux和Anolis,大家广泛使用的Ubuntu,CentOS也是大家用的比较多的,但因为CentOS 7已经EOL了,8也快了,所以我们建议之前使用CentOS的尽快迁移到阿里自研的ALinux上。另外Debain我们也有ARM版本的支持。

基于X86芯片开发的软件,我们一般要考虑它的指令问题。如果你用的是比较旧的ARM芯片,或者是在X86芯片,你使用了一般的指令,编译器就可以把所有的工作都做掉。但如果你使用了一些加速指令和一些特殊指令,在高版本的ARM上就要注意了,它的性能可能不会有更好的提升。比如你之前用的是Neo写的,现在到ECS倚天实例上建议你用SVE2来写,这样它的性能就会有成倍的提升或者数倍的提升。

对于一些特有的指令我们能保证可以向前兼容,但我们既然有更好的硬件芯片,我们当然推荐大家能做一些指令集方面的分析和优化,让你的软件在ECS倚天实例上把性能发挥的更好。




整个软件的迁移过程中,它的步骤很复杂。所以在我们出去交流的时候,很多客户和学术界的同学都会问,迁移的动作对专业性的要求太高了,是否有一些工具可以帮助我们便捷地把软件迁移过去。

阿里云经过两年的研发,同时根据客户的需求收集了一些产品的定义之后,推出了一个一键式软件迁移的工具叫EasyYitian。它可以帮助大家快速、简便、灵活地从X86上把软件迁移到ARM上。

我们提供了四个方面的功能:

第一,代码扫描翻译。我们可以给X86上的代码做一遍扫描,然后给出一个报告,告诉你往ARM上迁移要改哪些代码。此外,我们还支持一部分的翻译,但更多的是针对intrinsics,sve,avs512的指令集的层面,做一些代码的自动化翻译,翻译到ARM上。但对于大部分的通用软件,只需要改几行代码就能把软件迁移过来,并不需要翻译的动作。

第二,迁移环境构建。因为我们很多的客户希望自己的资产保存在自己可控的范围之内,他可以在自己的X86上搭建一个交叉编译环境。

大概在2016-2017年的时候,搭建交叉编译环境是非常困难的。因为交叉编译的环境里涉及一系列第三方的软件。当我们在做交叉编译的时候,不是说在X86上换了ARM的编译器就可以了,还要把周边的一些东西都给换掉。我们之前也尝试过虚拟机,但虚拟机的方式太笨重了。

现在我们再来看交叉编译,它就相对比较简单了。我们可以基于X86的环境搭建一个QEMU的虚拟环境,它是一个软件的模拟器,可以模拟ARM指令集的特征。在QEMU上我们再去搭建docker的镜像,这样就能把交叉编译的环境很便捷的帮客户准备好。此外,这个编译环境也可以共享,让你的同事和同学很快地把交叉编译环境搭建起来。

第三,系统扫描迁移。软件从X86迁移到ARM上,肯定会有一些依赖包、环境配置等一些工作。如果人去做的话,工作量是极其大的。这个工具可以帮助大家做自动化地扫描,便捷地让它在ARM上把环境设置好。当然这里面有一些配置,比如在X86上,它参数配置是针对X86芯片的,到了ARM上我们会有一些独特的配置方式在ARM上把它配好。会有一些专家调优的东西,甚至一些AI调优的东西。

第四,性能评估分析。EasyYiTian相当于一个软件集成的角色,我们可以把阿里云内部比较常用的软件,或者第三方看到的比较优秀的软件,把它包进来帮大家做软件管理助手的角色。

上图左侧是EasyYiTian的界面,右侧是一个例子,我从Linux上把一个RDMA的测试工具叫Pro test拿过来,它本身是X86上的东西。我去在EasyYiTian上做了一个扫描,然后它给了一些建议,告诉我如何修改可以改成ARM平台适用的软件。这里有大量的warning,即你需要注意的地方,这个可以忽略。有一个比较有价值的点就是在有内联函数上。



上图是具体示例,展示了问题代码的位置和内容。他会告诉你代码的哪一行有问题,需要你做改动才能从X86迁移到ARM上,否则就会出现问题。

这个改动主要指的是rdtsc指令,在X86上读实时的寄存器的时候,就直接通过rdtsc寄存器读出来之后就可以了。但在ARM上有很多的方法,ARM上没有这个寄存器,但有一些相对应的寄存器,上图中罗列了方法一、方法二、方法三,我们的用户可以根据自己的习惯和当时软件的场景去选择。



接下来介绍一下交叉编译环境的构建。刚刚也提到了交叉编译环境有点复杂,那么我们应该如何构建它呢?一般我们推荐大家走容器镜像的方式,因为这种方式比较轻量级,比较方便做镜像复制。

一般交叉编译用户需要四个步骤构建定制化的编译镜像:

第一步,一键配置QEMU基础环境。

第二步,选择目标OS。

第三步,根据系统扫描报告,在容器镜像中安装必要的软件包。

第四步,自动构建符合用户需求的容器镜像并输出。



下面举两个例子来介绍一下,我们在Java这种解释型语言里和C/C++这种编译型语言里,在做ARM平台编译的时候分别需要注意什么。

Java是解释型语言,理论上纯的Java应用跨架构运行是没有任何障碍的,但Java里面为了性能考虑,很多时候会通过调用一些C/C++编译的本地库。这种情况下,它就会产生一些迁移的成本。但总的来说解释型的迁移成本还是比较小的,具体步骤如下:

第一步,选择合适版本的JDK。推荐使用Java JDK 11和17,性能上会有比较好的提升。

第二步,Jar包。如果Jar包内嵌C/C++库的场景,可能是C/C++编译迁移的工作。

第三步,部署运行。我们有一些调优的建议,在ARM上需要对一些常用的参数做开关,来提升我们迁移后应用的性能。

阿里本身有很好的Java积累,Java团队在业界也是很有名的。我们在Github上有一个文档,介绍了Java的迁移知识。另外,在阿里云ECS文档手册里有一个ECS倚天实例的迁移中心,这里也有关于Java和C/C++等一些软件迁移的介绍。大家如果感兴趣可以自己去看一看。



C/C++代码在ARM平台的编译,看起来复杂,其实并不难。对于一些高性能场景,可能追求极致性能的可能会相对难一点,但对于绝大多数的通用场景,它对于性能没有强烈考量的情况下,执行一些简单的操作就能把编译的工作做完。具体步骤如下:

第一步,修改C/C++源码。

第二步,Makefile。

第三步,依赖库准备。

第四步,选择合理的编译器执行编译。


性能优化一直困扰着很多软件的同学,他们担心软件在X86上跑的好好的,迁移到ARM上性能就会变差。我想说性能优化肯定是有必要的,但我们也有一些工具已经帮大家把90%、甚至99%的应用做过优化了,大家用我们的一些经验就可以把优化的工作做掉。如果是自研的软件,当你要做优化的时候,我们也提供一些工具和指导,帮助你快速的把性能提升上去。此外,如果你的性能要追求极致,我们也提供一些专家服务,帮助大家去把性能的表现提升上来。

在选倚天的ECS实例的时候,有一个ECS Booster的优化套件,我们可以自定义或者直接选一下,这样就默认给你装好已经优化好的版本了。


ECS Booster背后的加速技术来源于阿里云KeenTune应用调优工具,它是开源、多架构、免费的,大家可以在网上自行搜索一下。阿里云KeenTune的调优方式主要有两种,分别是静态调优和动态调优。

静态调优是指,把专家的一些经验知识记录下来,然后在你的环境里扫描一遍。根据你的环境和我们之前记录下来的数据的匹配度,默认给你设置一些优化的参数,帮你优化整体的性能。这个性能不只是应用的性能,也包括了整个OS的性能表现。

动态调优是指,在静态调优的基础上,添加一些压力测试并收集测试的性能指标,然后用我们自研的AI调优算法,对应用做一些全值的参数调优。这里也可能潜在一些OS的少量参数调优,但整体而言我们都是针对应用做整体参数的调优以及收敛的,最后给出最佳操作。

上图右侧是一些实践。Ingress-nginx和典型的基础负载,在用了KeenTune之后,它们的性能提升的都非常明显。



最后,介绍一下如何部署。相对于我们传统的软件部署,基于云的软件部署是跨时代的,我认为它不是待机的,因为阿里云硬件的弹性非常的好,主推的CADT集群快速部署的功能可以快速的帮你把集群部署好。

在传统线下的数据中心,如果我们想部署环境,首先要租一个IDC机房,然后要把网络部署好,把服务器上电、调试,装操系统,最后再把软件部署上去并调试,这个过程没个把月,也有大十几天。而阿里云上提供了一些快速的弹性模板,可以帮你把集群搭建好。

这个模版包括官方的快速搭建的模板、用户之间共享的模板。此外,我们还可以通过自助拖曳来部署弹性服务器。



如果你觉得CADT还是有点重,我们还提供了一个更轻便的方式,阿里云容器服务ACK,它是阿里定义的一套类似于K8s的产品。它的底层内核也是基于K8s做的优化,我们提供了镜像托管服务ACR。可以让你在公司保密的层面上,通过K8s快速搭建一套阿里的K8s容器镜像服务,快速部署、快速启动。

但可能会存在一些问题,比如这个ACK集群里本来是有X86节点的,如果ARM节点进来之后要怎么办。因为ACK和ACR都支持多架构,把docker pool这个动作在某架ECS架构上执行的时候,它可以根据CPU架构直接找到对应的镜像。我们不用担心在X86上部署了ARM的软件,或者在ARM上部署了X86的软件。

另外,在X86和ARM的调度层面,我们支持混合调度。这背后的技术会有一点难度,因为X86和ARM的硬件特性让他们的任务负载以及真实的压力存在一定的差异。可以说ARM的真物理核在这里面体现了极高的优势,所以我们的CPU的水位可以打的比较高。

但X86的水位就不见得那么高了,这是由于X86超线程的原因。所以ECS倚天实例在混部场景上,希望有更多的压力,让ARM做更多的工作。而X86就不行了,因为超过一定的水位之后,它的性能会急剧下降。


三、典型迁移案例介绍


第一个案例,EMR迁移ARM实践及性能收益。EMR是阿里自研的大数据平台,和阿里的PAI类似,我们会对外提供一些PAAS服务,比如Spark、Hive、Flink等非常典型的大数据应用。在大数据平台底层,既有Hadoop一样非常经典的大数据平台软件,也有阿里自研的JindoSDK软件。它下面还有运行时的JDK,OS,还有ARM ECS的底座。整个数据栈看上去很复杂,但在ARM上迁移并不复杂。

上图罗列了一些典型的依赖包,大家可以根据这个清单看一下自己的软件要怎么做迁移。在从X86迁移到ARM之后,我们发现它的性能收益还是很明确的,比如Spark的性能提升了17%,Hive提升了27%,Flink提升了50%,这50%的提升主要来源于真物理核。

然后再来看一下迁移执行的情况,像Spark这种复杂的组件,基本上1.5个人月就可以把它全部搞定。包括迁移、性能优化、功能测试,最后完成多轮的压测之,就可以上线灰度使用了。



第二个案例,ARM实例购物车应用(Java)双11上线。电商的Java架构是一个很典型的Java的使用方式,这里有相关的软件版本信息供大家参考。

Java的迁移会更简单一点,基本上1个人月就能把事情都做完了。但可能就会有人问了,刚刚那么复杂的组件要1.5个人月,为什么Java的还有1个人月。这是因为这里的测试标准比较高,所以差不多24个工作日才把这个事情搞定。但一般企业在应用的迁移上不需要花费很长时间,这1个人月对于绝大部分企业来说是绰绰有余的。


四、阿里云跨架构迁移服务



倚天710芯片经过两年多时间的积累与沉淀,在通用计算场景、人工智能场景、云超算场景,都积累了比较丰富的经验。可以说我们在这些场景里,相对于X86我们会有一些优势,包括性价比的优势和性能的优势。

我们可以给我们的用户提供比较完善的、自动的代码分析修改工具和性能优化的工具,另外,我们对于重点客户提供了性能的专家服务支持。

以上就是本次课程的全部内容,同时想要了解更多精彩直播/观看课程回放的同学,可以扫描下方海报中的二维码/点击回看,均可观看课程。





相关标签: 芯片C容器弹性计算Java

本文地址:https://www.0558.la/article/859dc9271ab6e68fccaa.html

上一篇:测评优秀优质评测分享...
下一篇:新注册的域名多久可以备案新注册的域名要如...

温馨提示

做上本站友情链接,在您站上点击一次,即可自动收录并自动排在本站第一位!
<a href="https://www.0558.la/" target="_blank">自动秒收录</a>