从排查一次匪夷所思的coredump,引出各种体系架构的差异。

本文中的所有内容来自学习DCC888的学习笔记或者自己理解的整理,如需转载请注明出处。周荣华@燧原科技

1 背景

从全世界有记载的第一台计算机Z1 (computer) - Wikipedia在1936年发明,到1946年冯诺依曼体系架构的清晰提出,计算机体系架构的演进虽然没有什么革命性的变化,但各种体系架构的微调还是很明显的。

发展到现在虽然存在X86/ARM/MIPS/ALPHA/PPC/RISC-V等多种门派,但实际的设计思想上,主要有两种,一种是基于X86的系统架构,另外一种就是其他系统架构。

为什么这么分?

因为X86的很多特性,基本上只有X86有,而其他体系架构基本上都是共享的另外一种。

例如CISC和RISC,字节对齐,变长指令和固定长度指令,指令寻址模式,等等。

现在用的各种体系架构,只有x86是复杂指令集,变长,内存访问可以不是字节对齐的(当然,对齐之后性能更好),没有固定的加载和保存指令,而是采用很多计算指令直接访问内存。

相对于x86,其他体系架构,包括ARM/MIPS/ALPHA/PPC/RISC-V,都是精简指令集,指令长度也是固定的,内存访问必须对齐,否则coredump,内存的访问只能通过有限的几个加载和保存指令进行,其他计算指令仅限于在寄存器上操作。

2 体系架构

计算机的体系架构,英文称为Computer architecture - Wikipedia,涉及的工作主要分三部分:

指令集、微架构和系统设计。

其中指令集相当于用户界面,是软件和硬件的接口。

微架构是指令集的具体实现。

系统设计主要是支撑微架构的内存、总线、功耗等设计。

下面的问题单就X86来阐述。

32位的处理器太古老,我们单说64位之后的故事。

x86-64 - Wikipedia讲述了x86-64的体系架构的微架构演进过程:

最早出来的是x86-64,相当于64位x86的基线版本,基本上所有64位x86处理器都支持,包括常见的MMX、SSE、FPU,都不是问题。基于这个基线版本往上发展出了v2/v3和v4版本。

现在虚拟机(QEMU)基本上支持到v2就终结了,所以后面v3/v4变成了少数用户的选择。随着这些微架构的演进,不仅指令集,寄存器也会有较大变化。那怎么保证编译出来的程序在各种x86的硬件上都能正常运行是个大问题。解决这个问题的主角就是编译器。

考虑到泛化和性能的不同要求,即使在同样的体系架构下,也可以指定具体的硬件版本,这就是gcc/clang等编译器的arch参数的由来。

x86 Options (Using the GNU Compiler Collection (GCC))中提到的arch的取值从各种具体的处理器型号,到泛化的v2/v3/v4,都是为了方便程序员可以尽可能保证兼容性的前提下,也能提升性能。

如果不考虑泛化,用户还可以简单用一个-march-native在x86平台上实现基于当前硬件的极致优化。

3 问题

这里碰到的一个问题就是极致优化带来的兼容性问题。

某服务器上编译出来的版本,在部分x86的机器上能正常运行,但部分x86机器上不能正常运行。通过gdb断点排查,报非法指令,而且代码段指向vxorps这条指令,后面紧跟着的3个寄存器非常扎眼zmm。

zmm寄存器是v4版本引入的功能。

能运行含zmm寄存器指令的cpu是“Intel(R) Xeon(R) Gold 6130 CPU @ 2.10GHz”,网上查了一下,是intel 2017年的产品。

到目前位置,MMX指令使用的寄存器经过了三代演进,xmm/ymm/zmm:

xmm0 ~ xmm15, are 128 bits, almost every modern machine has it, they are released in 1999.
ymm0 ~ ymm15, are 256 bits, new machine usually have it, they are released in 2011.
zmm0 ~ zmm31, are 512 bits, normal pc probably don't have it (as the year 2016),

由于后一代的寄存器长度是上一代的两倍,决定了前一代处理器是无法使用后一代处理器的寄存器的,相反,本地如果是更高一级的寄存器,可以运行低级的寄存器相关指令。

同样的代码,都指定-march=native的情况下,在“AMD Ryzen Threadripper 3960X 24-Core Processor”上编译的结果是这样的,指令本身没有变,寄存器从zmm变成了xmm。

4 问题的解决

既然知道是gcc的arch指定有问题导致的,就要从修改arch入手。

做了一些实验,例如下面左边是-march=native编译,右边是-march=x86-64的结果。可以看出native编译出来使用incl,相对于addl,使指令更短,性能更好。

最终各种实验对比结果看结论如下:

-m64 -march=x86-64 -mtune=generic  编译出来的结果使用xmm寄存器
-march=native 编译出来的结果,在amd服务器上是xmm寄存器,在intel服务器上是zmm寄存器

为了保证兼容性,先统一用-m64 -march=x86-64 -mtune=generic 进行编译。

5 怎么做的更好

由于大多数编译器还不支持-march=x86-64-v2等直接选择x86-64具体版本的选项,有一种折中方案是native-avx512的做法,一般参数是这样的:

add_compile_options (-march=native)
add_compile_options (-mno-avx512f)

这样写的意思是其他方面可以尽量用本地能支持的最新的,但不要使用avx512f的功能,约等于x86-64-v3这个arch参数的功能。

关于cpu体系架构的一些有趣的故事分享的更多相关文章

  1. 【转】XenServer体系架构解析

    XenServer是一套已在云计算环境中经过验证的企业级开放式服务器虚拟化解决方案,可以将静态.复杂的IT环境转变为更加动态.易于管理的虚拟数据中心,从而大大降低数据中心成本.同时,它可以提供先进的管 ...

  2. 面向服务体系架构(SOA)和数据仓库(DW)的思考基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台

    面向服务体系架构(SOA)和数据仓库(DW)的思考 基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台 当前业界对面向服务体系架构(SOA)和数据仓库(Data Warehouse, ...

  3. 基于物联网操作系统HelloX的智慧家庭体系架构

    基于物联网操作系统HelloX的智慧家庭体系架构 智慧家庭是物联网的一个分支应用,是一个被广泛认同的巨大IT市场空间.目前市场上已经有很多针对智慧家庭的产品或解决方案,但与移动互联网不同,智慧家庭至今 ...

  4. [转]OpenContrail 体系架构文档

    OpenContrail 体系架构文档 英文原文:http://opencontrail.org/opencontrail-architecture-documentation/ 翻译者:@KkBLu ...

  5. InnoDB引擎体系架构

    InnoDB引擎架构介绍 innodb存储引擎的体系架构,可简单划分成三层: 数据文件 :磁盘上的数据文件 内存池:缓存磁盘上的数据,方便读取,同时在对磁盘文件数据修改之前在这里缓存,然后按一定规刷新 ...

  6. InnoDB体系架构(二)内存

    InnoDB体系架构(二)内存 上篇文章 InnoDB体系架构(一)后台线程 介绍了MySQL InnoDB存储引擎后台线程:Master Thread.IO Thread.Purge Thread. ...

  7. InnoDB体系架构

    MySQL支持插件式存储引擎,常用的存储引擎则是MyISAM和InnoDB,通常在OLTP(Online Transaction Processing 在线事务处理)中,我们选择使用InnoDB,所以 ...

  8. NUMA 体系架构

    NUMA 体系架构 SMP 体系架构 NUMA 体系架构 NUMA 结构基本概念 Openstack flavor NUMA 策略 Nova 实现 NUMA 流程 1. SMP 体系架构 CPU 计算 ...

  9. 面向服务体系架构(SOA)和数据仓库(DW)的思考

    摘要: 当前业界对面向服务体系架构(SOA)和数据仓库(Data Warehouse,DW)都介绍的很多,提出了很多优秀的解决方案,但是一般是把 SOA 和 DW 单独考虑,SOA 和 DW 有着共同 ...

随机推荐

  1. 使用fastai训练的一个性别识别模型

    在学习了python中的一些机器学习的相关模块后,再一次开始了深度学习之旅.不过与上次的TensorFlow框架不同,这一次接触的是fast.ai这样一个东西.这个框架还不稳定,网上也没有相关的中文文 ...

  2. Linux_yum源仓库-本地-网络-练习实验

    1.本地光盘挂载使用yum源 实验环境centos8 系统版本CentOS-8.3.2011-x86_64-dvd1 1)配置前检查 1.1 虚拟机设置选择对应版本镜像文件 1.2 启动虚拟机后处于连 ...

  3. 文件共享总结下篇-NFS学习笔记

    一.NFS原理 ## 本次实验以CentOS7.7为例 [root@qll251 ~]# cat /etc/redhat-release CentOS Linux release 7.7.1908 ( ...

  4. 并发编程系列之Lock锁可重入性与公平性

    一.相似之处:Lock锁 vs Synchronized 代码块 Lock锁是一种类似于synchronized 同步代码块的线程同步机制.从Java 5开始java.util.concurrent. ...

  5. Git 上传文件项目到github,gitee详细教程!(本文用的gitee)

    1:安装Git 下载地址:https://git-scm.com/ 2:生成ssh密钥不会的可以去另一篇文章 https://www.cnblogs.com/psfjc/p/15980893.html ...

  6. Fail2ban 简介

    Fail2ban是一个基于日志的IP自动屏蔽工具.可以通过它来防止暴力破解攻击. Fail2ban通过扫描日志文件(例如/var/log/apache/error_log),并禁止恶意IP(太多的密码 ...

  7. Jwt隐藏大坑,通过源码帮你揭秘

    前言 JWT是目前最为流行的接口认证方案之一,有关JWT协议的详细内容,请参考:https://jwt.io/introduction 今天分享一下在使用JWT在项目中遇到的一个问题,主要是一个协议的 ...

  8. SpringBoot 错误(2)

    springBoot整合redis时,报错如下: org.springframework.data.redis.serializer.SerializationException: Cannot de ...

  9. R-CNN学习笔记

    R-CNN学习笔记 step1:总览 步骤: 输入图片 先挑选大约2000个感兴趣区域(ROI)使用select search方法:[在输入的图像中寻找blobby regions(可能相同纹理,颜色 ...

  10. GoF的23种设计模式的功能

    GoF的23种设计模式的功能 前面说明了 GoF 的 23 种设计模式的分类,现在对各个模式的功能进行介绍. 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取 ...