openSUSE:X86-64-架构级别

跳转到:导航搜索


问题陈述

CPU 随着时间的推移会获得新的指令。openSUSE Tumbleweed 为所谓的 x86-64(又名 x86-64-v1、x86_64、基线、AMD64)构建整个发行版。这意味着编译器必须确保二进制文件能够在不支持较新功能的 CPU 上运行,这可能会导致性能低于最佳,因为它在优化期间避免了更高级的功能(例如 SSE 4.2、AVX2)。要利用这些功能,源代码必须特别注意在运行时检测它们。

至少有两种方法,一种现在就可以实现,另一种我们建议实施。


可用选项:以 x86-64-v2 构建所有内容

只需将 Tumbleweed 的最低硬件要求提高到需要一个能够运行 x86-64-v2 CPU,并将所有软件包构建为该新基线的 x86-64 软件包。这意味着较旧的硬件不再受这些软件包的支持。要解决此问题,需要另一个具有单独仓库等的发行版完整构建。

优点

  1. 最简单的选项,可以与第 3 方 x86-64.rpm 软件包混合和匹配
  2. 只需交付一套二进制文件和库
  3. 与现有的 openQA 和 openSUSE 构建服务构建工作站硬件具有良好的兼容性
  4. 可以与其它选项结合使用,例如,为特定库提供 hwcaps -v4 覆盖
  5. 所有 CPU 都与为 Windows 11 编译的程序兼容(可能使用 x86-64-v2 指令,例如 POPCNT)

缺点

  1. x86-64-v2 带来的好处微乎其微,甚至对整个发行版没有好处。虽然某些特定应用程序受益匪浅,但它们通常已经具有特定的处理机制,这些机制会根据运行时 CPU 功能进行热补丁。在其他领域,预计不会有显着的好处。
  2. 发行版的代码尺寸略有增加
  3. 可能会破坏上游假设,并需要修补各种软件包(几个上游软件包会进行自己的 CPU 选择并构建多个变体,无法处理“基本”变体实际上不再与旧版本兼容,在某些情况下会破坏测试套件)
  4. 根据社区反馈,停止对旧 x86-64 硬件的支持存在争议,提供“LegacyX86”发行版的缓解措施需要大量资源(人力 + 构建能力)


可用选项:利用 glibc hwcaps 目录

Glibc 从版本 2.33 开始支持 hwcaps。这允许为 x86-64 = x86-64-v1 构建基本系统,并为更高的级别构建库到特定的目录,例如 /usr/lib64/x86-64-v[2,3,4]。然后,Glibc 将加载适当的库,即如果适用,则加载 x86-64-vX 子目录中的库,并回退到 /usr/lib64 的基线。

默认架构级别不会更改。对于手动选择的一组库或为 `baselibs.conf` 启用的所有库,我们可以在单独的仓库中构建 x86-64-v3 变体。这些不会执行正常的共享库 rpm 依赖项提供,而只是*补充* x86-64-v1 软件包。因此,对于正常的依赖项解析,将安装 x86-64-v1 软件包,从而提供与第 3 方软件的最大兼容性。

优点

  1. 可以为所有共享库或所有库的子集提供更高的级别(-v3、-v4),构建和测试资源影响可以灵活选择。
  2. 可以使用单个安装介质/路径,因为主要架构要求没有改变。速度提升会自动应用,当安装额外的可共同安装的软件包时不会破坏兼容性,这对于云原生容器化环境非常重要,因为容器可以在不同 CPU 代的硬件之间迁移
  3. 没有代码尺寸或基本架构级别提升
  4. 与现有的 openQA 和 openSUSE 构建硬件以及社区的“足以用于 Linux”硬件最大兼容
  5. 不需要对软件包进行大量的源代码修改,只需使用不同的 %libdir 设置和 baselibs 样式的自动重新打包为 .x86-64.rpm,并使用新的软件包名称(例如 `libzstd1-64bitv3.x86-64.rpm`)。
  6. 可共同安装的共享库
  7. 与现有的 spec 文件高度兼容,因为不需要实现新的架构检测(现有的架构和主架构与以前相同。只有那些可以单独测试或修补上游后启用或禁用的优化才会进行优化)。
  8. 需要额外的 weakobsoletes 处理,以避免剩余的共享库
  9. 无需重新安装系统即可在微架构级别上优化向上或向下。优化向下会自动发生(安全行为),优化向上需要安装额外的软件包模式。

缺点

  1. 只有共享库针对更高的架构级别进行优化。静态链接的二进制文件仍然是 x86-64-v1(这也是一个功能,因为它最大限度地提高了互操作性)
  2. 无法生成仅 -v3 发行版,只能生成 -v1 加上高于 1 的一个或多个 -vX 级别,从而增加了新硬件磁盘空间要求,这些硬件希望利用优化的构建(权衡:小安装尺寸 - 更兼容且库优化程度较低,或更大的安装尺寸与库优化程度更高)
  3. 当存在关于 `%_libdir == %_prefix/%_lib` 的硬编码假设时,可能需要修补源代码包(这对于 -v3 hwcaps 构建不成立,其中 %_libdir 是 `%_prefix/%_lib/x86-64-v3`)。
  4. 当“常规”共享库软件包的版本比 hwcaps 覆盖版本更新或旧版本时,可能会导致版本漂移(可能导致互操作性问题)。也许可以通过额外的冲突“sharedlibpacakge != %{version}”来解决。


可能的选项:分离 RPM 架构

就像 32 位 ARM (armv5, v6, v7) 或 x86 (i586, i686) 一样,我们建议为 x86-64 使用子架构。这将允许我们构建一个多架构仓库(例如 x86-64(-v1) 加上 x86-64-v3)并发布它。在安装软件包期间,将选择系统支持的最高级别的软件包。

优点

  1. “干净”的解决方案,允许安装仅 -v3 或 -v4 系统,而无需安装其他架构级别的额外二进制文件
  2. 支持对共享库之外的优化(静态二进制文件,..)

缺点

  1. 无法使用单个安装介质
  2. 需要修补数千个软件包(例如 %ifarch x86-64 -> %ifarch %x86-64)以及修补上游中所有假设 $(uname -m) == rpmarch 的位置。
  3. 为了受益于优点,需要为架构构建 tumbleweed 的完整构建,这意味着将所需的构建资源(磁盘、计算和网络传输)翻倍或三倍
  4. 由于无法共同安装的软件包,因此无法混合和匹配
  5. 需要与 rpm 上游就该方法达成一致。之前的尝试 (https://github.com/rpm-software-management/rpm/pull/1035 ) 已被拒绝。
  6. 需要在各种软件管理和监控软件(第 3 方软件/ISV 软件)中实现架构回退
  7. CPU 功能可以更改(例如,将磁盘从一台计算机传输到另一台计算机,例如在不同的 kubernetes pod 上重启容器),而软件包管理器无法控制或影响,从而在这些情况下破坏互操作性
  8. 异构 CPU 架构(例如,具有不同微架构级别的经济核心或性能核心)不支持此提议。

需要对此进行调整的组件

  1. RPM(添加带有兼容性标记的新子架构)
  2. Zypper(libzypp/libsolv,以配合使用 ^)
  3. OBS(以识别新的架构)
  4. 容器引擎(以便并排发布 -v1/-vX 镜像)


可能的选项:逐步进行

使用 x86-64-v1 和 x86-64-v2 的超集编译代码。附加级别

  1. x86-64-v1a = x86-64-v1 + SSE3(参见 Bug 1182220
  2. x86-64-v1b = x86-64-v1 + SSE3 + CMPXCHG16B
  3. x86-64-v1c = x86-64-v1 + SSE3 + CMPXCHG16B + LAHF/SAHF
  4. x86-64-v1d = x86-64-v1 + SSE3 + CMPXCHG16B + LAHF/SAHF + POPCNT

看起来所有具有 2 个或更多核心的 x86-64 CPU 都支持 SSE3。这意味着我们可以在不损失兼容性的情况下获得一些速度提升。
x86-64-v1d 受到 Intel Nehalem(2008 年)及更高版本的支持 - POPCNT 属于 Intel 的 SSE 4.2。对于 AMD,它受到 AMD K10(2007 年)架构(AMD Family 10h、AMD Barcelona、Phenom 及其衍生产品)及更高版本的支持 - POPCNT 属于 ABM(高级位操作),是 SSE4a 的一部分,或者如果 SSE4a 不可用,则属于 SSE 4.2。

优点

  1. 兼容性

缺点

  1. 小优势


决策

OpenSUSE Leap 16.0 使用 x86-64-v2 与旧硬件兼容。还支持传统启动。来自 SUSE SLE 16 的软件包将具有“回溯”仓库,其特征尚不清楚(v2 或 v3?)。

OpenSUSE Tumbleweed 仍然使用 x86-64,又名 x86-64-v1。


参见