Power平台迁移指南

2023-05-16

在使用Power平台过程中,可能会遇到现有X86平台的应用程序无法在Power平台中直接运行的问题,这是由Power平台与X86平台的架构差异造成的,因此需要通过软件迁移对相关应用进行基于Power平台的适配。迁移工作首先是指令集的适配,该部分工作通过使用合适的编译器及部分代码修改即可完成,同时针对Power处理器Cacheline大、支持的页框大等特性,也需要对应用代码进行针对性的调整,以充分发挥Power处理器的硬件优势,最终实现应用程序的稳定高效运行。

最近我在浪潮商用机器的官方微信上,看到了一篇文章,只需三步:①Set up好环境,②指令集编译,③代码优化,即可轻松地把X86上的应用迁移到Power上来,进而享受Power集成的一体化应用管理环境、卓越的性能、优异的拓展性、卓越的安全性以及简化的系统管理等优势。当然原文有一定的局限性,我做了一些增补和修改,以下是我亲历的整个过程。

1软件迁移的必要性

1.1程序执行过程

所有的软件均由编程语言实现,编程语言在计算机上最终会被翻译成机器语言,以指令的形式在处理器上执行。

1.2Power处理器和X86处理器的指令差异

处理器能够识别的所有指令的集合就是指令集,而不同架构处理器所使用的指令集是不同的。Power架构处理器使用的是基于RISC(Reduced Instruction Set Computing)的ISA指令集,而X86架构使用的是CISC(Complex Instruction Set Computing)指令集。

因此,X86架构下软件在Power平台上运行必须经过相应的迁移。

1.3迁移过程中的常见问题类型

  1. Makefile文件及configure文件兼容性问题

Makefile文件中不同架构使用的编译选项可能会有所不用,如果Makefile文件使用不当会导致编译问题,通常编译时会使用Configure来生成Makefile文件,因此需要在Configure文件中加入相应的架构选项,在Power平台编译时需要加入PPC64le架构选项。

例如Python2.7的configure.guess,需要在configure.guess中增加对Power架构的支持:

ppc64le:Linux:*:*)

    GUESS=powerpc64le-unknown-linux-$LIBC

    ;;

ppcle:Linux:*:*)
    GUESS=powerpcle-unknown-linux-$LIBC
    ;;

vax:Linux:*:*)

    GUESS=$UNAME_MACHINE-dec-linux-$LIBC

    ;;

x86_64:Linux:*:*)

set_cc_for_build

GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
  1. 汇编指令兼容性问题

不同平台使用的汇编指令是完全不同的,跨平台执行汇编指令会触发指令异常,因此在Power平台编译软件时需要将软件代码中的X86平台的汇编指令执行进行相应的替换。

如CPU序列号获取功能,需要对X86的汇编指令进行如下替换:

X86:
asm volatile
    (
    "movl $0x01, %%eax; \n\t"
    "xorl %%edx, %%edx; \n\t"
    "cpuid; \n\t"
    "movl %%edx, %0; \n\t"
    "movl %%eax, %1; \n\t"
    : "=m"(s1), "=m"(s2)
    );

PPC64le:
从"/proc/device-tree/vpd/"系统文件读取

2.unsign char问题

X86 平台中,GCC编译器默认char为有符号类型,比如char a = -1 GCC编译器则默认为signed char a = -1,其二进制原码为10000001,它的补码是除了符号外取反加 1,补码为 11111111,在计算机中数值是以补码形式存储,同样为 -1在计算机中存储的二进制 11111111,由于Power平台中GCC编译器对char 默认是无符号类型且计算机中无符号数的原码、补码的值相同,因此其表示的数值为 255。所以代码编译时需要加入-fsigned-char 编译选项以避免这个问题,如下所示:

gcc -fsigned-char -o transfer *.c

3.类型转换溢出的问题

双精度浮点型转整型或者浮点型时,不同架构处理器的算数逻辑单元的实现会有差异,编译器的实现也有所不同因此Power平台与X86平台相比上述转换操作会有不同的结果。在X86的转换指令中定义了一个 indefinite integer value(0x8000000000000000)表示出现溢出问题。 而Power平台的转换策略则是无论是正数溢出还是负数溢出,转换结果为转换目标类型(整型/浮点)的最大或最小值,因此在移植过程中需要对上述类型转换进行重点关注,避免不同转换结果引起的问题。具体差异参见下表

处理器

Double值

转换为long结果

描述

X86

正值超出long范围

0x8000000000000000

indefinite integer value

负值超出long范围

0x8000000000000000

indefinite integer value

Power

正值超出long范围

0x7FFFFFFFFFFFFFFF

long最大值

负值超出long范围

0x8000000000000000

long最小值

处理器

Double值

转换为int结果

描述

X86

正值超出int范围

0x80000000

indefinite integer value

负值超出int范围

0x80000000

indefinite integer value

Power

正值超出int范围

0x7FFFFFFF

long最大值

负值超出int范围

0x80000000

long最小值

4.XCHGL问题:

chgl 是 x86 上的汇编指令,作用是通过原子操作交换内存变量的值,Power平台提供lwarx/ldarx及stwcx/stdcx指令组合来实现内存变量的原子交换

__xchg_u64_local(volatile void *p, unsigned long val)

{

        unsigned long prev;

        __asm__ __volatile__(

"1:     ldarx   %0,0,%2 \n"

        PPC405_ERR77(0,%2)

"       stdcx.  %3,0,%2 \n\

        bne-    1b"

        : "=&r" (prev), "+m" (*(volatile unsigned long *)p)

        : "r" (p), "r" (val)

        : "cc", "memory");

5.SIMD扩展指令兼容性问题

目前不同平台均可以通过SIMD(单指令多数据流)扩展指令集提供向量技术,但不同架构平台提供的指令集完全不同,X86平台使用MMX/SSE/AVX指令集,而目前Power平台目前使用VSX指令集

如:popcnt指令,需要在代码中将X86的SSE指令集替换为PPC64le的指令:

X86:
#define popcnt(x) asm("popcnt %[x], %[val]” : [val] "+r" (x) : : "cc")

PPC64le:
#define popcnt(x) __builtin_popcount(x)

6.内存页大小兼容性问题

不同架构平台使用的内存页大小有所差异,X86平台使用页大小为4KB,Power平台默认使用的页大小为64KB,如果应用程序中使用了错误的页大小会导致不可预测的问题。

如MozJS17(Mozilla JavaScript 引擎)代码中将Page Size固化为4KB导致在64KB内存页大小的平台中运行时产生段错误,因此需要修改Page Size为64KB:

#if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))

    const size_t PageShift = 13;

    const size_t ArenaShift = PageShift;
#elif defined(__powerpc__) || defined(__aarch64__)
    const size_t PageShift = 16;

2软件迁移步骤
 

整个软件迁移需要经过四个步骤:迁移准备软件分析编译迁移优化

2.1迁移准备

Power平台环境准备,可采用下列任意一种方式:

  • 向浪潮商用远程测试中心申请迁移测试环境
  • 本地可连接网络的Power服务器

2.2软件分析

本阶段主要进行被迁移软件的软件栈分析及迁移策略制定。

2.2.1
软件栈分析

  • 基础环境分析:分析当前软件的基础环境,主要包括操作系统、中间件、编译器等,以便于后续软件迁移时尽可能的让Power平台的基础环境与之对齐,尽量减少两者的差异。
  • 上层应用分析:分析软件包及其依赖组件,根据能否获得源码,将待移植软件及其组件分为开源/自研以及闭源两种类型,不同类型的软件采取不同的迁移策略。

2.2.2
开源/自研软件

对于开源/自研软件而言,可以根据实现软件编程语言类型的不同制定不同的迁移策略。高级编程语言通常可以分为两类:一类是编译型语言,一类是解释型语言。编译型语言通过编译器生成机器语言程序,机器语言程序可以直接被CPU执行;解释型语言通过对应的语言虚拟机或者解释器执行,语言虚拟机或者解释器屏蔽了不同CPU架构的差异。

翻译方式

迁移策略

编译型语言

源码:重新编译

依赖组件:获取Power版本或者下载源码重新编译,闭源组件需要替换Power版本或替换类似组件库

解释型语言

替换Power版本的语言虚拟机或者解释器,如JDK或Python解释器

依赖组件:获取Power版本或者下载源码重新编译,闭源软件需要替换Power版本或者替换类似组件库

2.3编译迁移

由于解释型语言迁移相对简单,我们将重点介绍编译型语言的迁移过程,主要需要进行编译构建脚本和C/C++源码的修改。

2.3.1
解释型语言

直接翻译:对于解释性语言实现的程序,代码无需修改,程序也不需要重新编译,直接替换对应Power版本的语言虚拟机或者解释器即可,如系统自带的OpenJDK及Python解释器。

依赖库编译:如果软件包含由编译型语言实现的依赖库,则需要获取依赖库对应的Power版本,如无法获取可用的Power版本,则需下载依赖库的源码包重新编译依赖库。

2.3.2
编译型语言

编译环境准备

安装支持Power平台的编译器,目前可用的编译器如下:

GCC4.8.5及以上版本、LLVM8.0及以上、IBM XLC/C++、IBM XLF、IBM AT(IBM Advance-toolchain)

编译选项移植

  • Configure文件中增加适配PPC64le编译选项,例如使用支持PPC64le架构的config.guess
  • 显式定义Char类型变量为有符号类型,在Makefile文件中添加“-fsigned-char”编译选项(X86默认是有符号数,Power平台默认是无符号数)
  • Power平台不支持MMX/SSE/AVX指令,去掉“-msse”、“-msse4.1”等AVX编译选项

编译宏移植

  • GCC编译器自定义平台属性编译宏:将“__X86_64__”或“__x86_64”替换为“__powerpc64__”
  • 用户自定义平台属性编译宏:例如将“HAVE_X86_64”替换为“HAVE_POWERPC64”

源码移植

  • SIMD扩展指令集移植:

①MMX/SSE代码适配:升级到GCC 8+,添加编译选项“-DNO_WARN_X86_INTRINSICS”或者直接修改代码,使用VSX指令进行替换

②AVX代码适配:使用VSX指令进行替换

  • 汇编指令移植:

Power的汇编语言与X86的完全不同,所有涉及到使用汇编语言的代码,都需要基于Power进行移植。

2.4优化

2.4.1编译器优化

可以将GCC升级为以下两种编译器:

  • IBM XLC/C++、IBM XLF,IBM发布的针对C/C++及Fortran的编译器,针对Power平台进行了深度优化,提高应用程序运行效率
  • IBM AT(IBM Advance-toolchain),IBM发布的充分利用Power硬件特性的编译工具集,包含了最新版本的编译器(基于GCC)、更完整的功能库、DEBUG分析工具等

2.4.2编译选项优化

GCC/AT编译选项:-O3 -flto -funroll-loops -ffast-math -mcpu=power9 -mtune=power9

XLC/C++编译选项:-O3 -qhot -qipa -qpdf2 -qarch=pwr9 -qtune=pwr9

XLC/C++编译选项

GCC/AT编译选项

优化内容

-O3

-O3

提高代码的并行执行度,充分利用CPU的流水线、Cache等

-qhot

-funroll-loops

循环优化以及函数内联,可以得到较好的程序性能

-qipa

-flto

跨编译单元优化,适用于调用小函数特别多的场景

-qpdf1-qpdf2

-fprofile-generate-fprofile-use

反馈式编译优化,适用于大量的跳转或分支以及间接函数调用等 

-

-ffast-math

触发non-standards-compliant浮点优化,适用于浮点精度要求不高的浮点计算优化

-qarch=pwr9

-mcpu=power9

针对POWER9的架构优化

2.4.3组件库优化

使用IBM提供的针对Power平台深度优化过的组件库,如IBMESSL、IBM SpectrumR MPI。

2.4.4OpenJDK优化

Power平台与X86平台相比,需要增加针对垃圾回收的优化:

-XX:+UseParallelGC -XX:+UseAdaptiveSizePolicy -XX:ParallelGCThreads=4

2.4.5代码优化

  • 基于Cacheline数据对齐调整:为提升Cache读写效率,同时避免Cacheline伪共享问题影响程序性能,可在程序代码中进行Cacheline对齐。Power上Cacheline Size是128 Bytes,X86 Cacheline Size是64 Bytes,代码需要针对Power平台Cacheline Size大小进行相应调整。例如:
  • struct {
        int count __attribute__((aligned(128)));
    } counts[N_CPUS]; 


  • 该版本已经上传至GitHub,供开源社区小伙伴们查阅使用:基于内存页数据对齐调整 :应用程序通过基于内存页的数据隔离以避免高并发时的内存资源竞争问题,提升程序性能。Power上Page Size是64KB,X86上Page Size是4KB,一些应用中显式指定了Page Size的大小来实现,这种情况下代码需要针对Power平台Page Size大小进行调整。例如:
  • long page_size =sysconf(_SC_PAGE_SIZE);
    void *data;
    size_t data_size = (size_of_data);
    posix_memalign(&data,page_size, data_size);

https://github.com/powerfans/PortingSW2POWER

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Power平台迁移指南 的相关文章

  • apache两种工作模式详解

    http blog chinaunix net space php uid 61 20541969 amp do 61 blog amp id 61 351485 刚接触这两个配置时很迷糊 xff0c 全部开启或全部注释没有几多变化 今天搜
  • Apache处理http请求的生命周期

    Apache请求处理循环详解 Apache请求处理循环的11个阶段都做了哪些事情呢 xff1f 1 Post Read Request阶段 在正常请求处理流程中 xff0c 这是模块可以插入钩子的第一个阶段 对于那些想很早进入处理请求的模块
  • 提高MySQL插入记录的速度

    http hi baidu com jackbillow blog item 65ea47248f645521d50742e7 html 在myisam engine下 1 尽量使用insert into table name values
  • 最常用的http状态码

    200 OK 找到了该资源 xff0c 并且一切正常 202 Accepted 服务器已接受请求 xff0c 但尚未处理 amp bsp 301 Moved Permanently 被请求的资源已永久移动到新位置 302 Found 请求的
  • shell中通过ftp批量上传文件

    为了在shell中上传文件 xff0c 需要避免在控制台中通过交互的方式输入ftp的登录密码 xff0c 这时要安装一个强大的ftp命令行工具 xff1a lftp xff0c 通过lftp登录ftp服务器的格式如下 xff1a lftp
  • 你可能不了解的strtotime函数

    出处 xff1a http www phppan com 2011 06 php strtotime 作者 xff1a 胖胖 在前面的文章中 xff0c 我们提到strtotime函数在使用strtotime 1 month 求上一个月的今
  • PHP的词法解析器:re2c

    出处 xff1a http www phppan com 2011 09 php lexical re2c 作者 xff1a 胖胖 re2c是一个扫描器制作工具 xff0c 可以创建非常快速灵活的扫描器 它可以产生高效代码 xff0c 基于
  • 由浅入深探究mysql索引结构原理、性能分析与优化

    出处 xff1a http www phpben com post 61 74 摘要 xff1a 第一部分 xff1a 基础知识 第二部分 xff1a MYISAM 和 INNODB 索引结构 1 简单介绍 B tree B 43 tree
  • php的strtotime函数源码分析

    最近想实现一个多语言版的strtotime函数 xff0c 所以阅读了php源码中strtotime函数的实现 xff0c 很感谢 胖胖 大大的文章 xff08 http www phppan com 2011 06 php strtoti
  • 新浪微博,腾讯微博mysql数据库主表猜想

    出处 http blog csdn net cleanfield article details 6339428 注意 xff0c 原文下面的评论也是难得的学习资料 xff0c 千万不能错过 用户信息表 xff08 t user info
  • linux shell 常见的时间戳操作

    获取当前的时间戳 span class hljs keyword date span 43 span class hljs variable s span 获取某个时间点的时间戳 span class hljs keyword date s
  • Mantis: SVN integration in 1.2.x

    http blog crazytje be mantis svn integration in the 1 2 x Recently I upgrade my mantis version from 1 1 8 to 1 2 6 first
  • Mantis SVN Integration : Adding extra info to the Note

    http blog crazytje be mantis svn integration adding extra info to the note In my previous post I talked about Mantis and
  • 一次向svn中增加所有新增文件 svn add all new files

    http wp4d sinaapp com 2012 02 19 E4 B8 80 E6 AC A1 E5 90 91svn E4 B8 AD E5 A2 9E E5 8A A0 E6 89 80 E6 9C 89 E6 96 B0 E5
  • codeigniter 对数据库的常用操作

    http www thenbsp com view codeigniter database codeigniter CI 是一个优秀 敏捷的PHP开源框架 xff0c 尤其封装了对数据库的操作 xff0c 很方便 xff0c 以下是php
  • mantis整合svn续:把提交的所有信息自动保存为note

    在前面两篇转载的文章中 xff0c 介绍了mantis和svn的整合 http blog csdn net newjueqi article details 7785373 http blog csdn net newjueqi artic
  • IM:手机客户端和服务端通信的资料

    Android平台下基于XMPP的IM研究 一 http blog csdn net liuhongwei123888 article details 6340757 Android平台下基于XMPP的IM研究 二 MultiUserCha
  • 像素和分辨率的关系

    像素 xff1a 每张图片都是由很多个色点组成 xff0c 每个色点称之为像素 xff08 Pixel xff09 分辨率 xff1a 是指单位长度中所表达或者截取的项目数 我们通常所说的摄像机的分辨率指的是图像分辨率 xff0c 表示每英
  • 基于PHP构建OAuth 2.0 认证平台

    http www jouhu com blog p 61 2024 基于PHP构建OAuth 2 0 认证平台 1 三月 2012 7 47 下午 各大门户都推出了三方API xff0c 如Google Facebook QQ Sina A
  • OAuth - 基本概念

    http lds2008 blogbus com logs 120393356 html 1 基本概念 1 1 词汇表 Client HTTP客户端 具有发送OAuth authenticated请求能力的HTTP客户端 Server HT

随机推荐