从排查一次匪夷所思的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. Docker部署PostgreSQL主从

    #准备 PostgreSQL12.3版本容器两台,部署参考https://www.cnblogs.com/zspwf/p/16113298.html 主库: 192.168.3.14:2200 从库: ...

  2. JVM组成、GC回收机制、算法、JVM常见启动参数、JAVA出现OOM,如何解决、tomcat优化方法

    JVM组成.GC回收机制.算法.JVM常见启动参数.JAVA出现OOM,如何解决.tomcat优化方法

  3. Unity—TextMeshPro

    矢量文字,不会因为放大缩小而变的不清晰: 1.TextAsset Window/TextMeshPro/Font Assets Creator 创建TextAsset字体: SourceFont是.t ...

  4. 简单的TRPG骰子

    又到了新一年的带团季了,今年准备用电脑来存放各种资料,自然也是需要一个简单的骰子工具了,反正也不复杂,就自己写了个,放着做个备份吧 主要功能是计算x1dy1+/-x2dy2+/-.....+/-con ...

  5. Vert.X CompositeFuture 用法

    CompositeFuture 是一种特殊的 Future,它可以包装一个 Future 列表,从而让一组异步操作并行执行:然后协调这一组操作的结果,作为 CompositeFuture 的结果.本文 ...

  6. 卧槽!华为《Linux中文手册》火了,完整版 PDF 开放下载!

    这是华为工程师基于最新的Linux编写,循序渐进地对Linux进行讲解.对于零基础可以作为Linux的快速入门教材.我希望能为大家提供切实的帮助. 资料介绍 涵盖基础.系统管理.应用.开发.服务器配置 ...

  7. height不确定时,如何使用动画效果展开高度

    要点: 当元素 height 不确定时,可以使用 max-height 设置动画效果 a[href="foldBox"] 用于打开 #foldBox(利用伪元素 :target) ...

  8. JuiceFS v1.0 beta3 发布,支持 etcd、Amazon MemoryDB、Redis Cluster

    JuiceFS v1.0 beta3 在元数据引擎方面继续增强,新增 etcd 支持小于 200 万文件的使用场景,相比 Redis 可以提供更好的可用性和安全性.同时支持了 Amazon Memor ...

  9. sublime速查手册

    零.sublime的优势 容易上手 支持多点编辑 包管理:Package Control 速度快 深度可订制,配置文件放github上 sublime-config 快速文件切换 cmd + p 输入 ...

  10. 好客租房57-props深入(4props的默认值)

    1给props设置默认值 //导入react     import React from 'react'     import ReactDOM from 'react-dom'     import ...