【问题标题】:Verifying compatibility with legacy Intel processors验证与旧版 Intel 处理器的兼容性
【发布时间】:2015-12-27 10:19:36
【问题描述】:

我有一个应用程序旨在针对广泛的英特尔处理器系​​列,从古老的(奔腾、奔腾 ​​II)到现代(Haswell、Skylake)。它具有为 x86 指令集(SSE、AVX 等)的各种扩展量身定制的特定代码路径。但是,我只能访问可追溯到 Sandy Bridge 的计算机,并且无法验证该应用程序是否真的可以在支持的最旧架构上运行。虽然确实旧的 CPU 不太可能用于任何用途,但从代码质量的角度来看,知道名为 my_routine_sse2 的函数不会意外使用来自 SSE3 等的指令是一件好事。

面对此类问题,人们通常会采取哪些方法?是否有可以扫描功能并确保不存在非法指令的自动化工具?是否有服务(网络或其他)提供对旧计算机架构的访问以进行测试和调试?

【问题讨论】:

  • 实际在 Bochs 下运行应用程序对于积极开发来说可能太慢了。不过,它可以用于发布验证。
  • 我想在现代 CPU 上运行 Bochs 至少与在过时的本机 CPU 上运行一样快(如您所述,用于验证)。不过不确定。
  • 英特尔至强融核协处理器(Knights Corner)基于大约 1995 年的 P54C 内核...
  • x264 对 SSE 使用手写 asm,而不是 C 内部函数。他们使用带有 .cpu 宏的 YASM 来检查声称仅 SSE2 的函数是否不会意外使用任何后续指令。该检查发生在组装时。同样,我认为 gcc 通常会抱怨如果您使用要编译的目标不支持的向量内在函数,我不确定这种不应该提供的内在函数的缺乏定义有多强大。在一种情况下(至少),相同的内在函数可以生成具有差异要求的指令:AVX1:VBROADCASTSS x/ymm, m32。 AVX2:VBROADCASTSS x/ymm, xmm

标签: x86 compatibility executable intel backwards-compatibility


【解决方案1】:

制作可以在 bochs 下运行的单元测试,以测试您的所有 my_routine_sse2 等功能。

您仍然需要偶尔测试整个应用程序,以确保您没有搞砸 CPU 调度程序,或者在调度程序控制的函数之外包含一些非基线指令。

顺便说一句,函数指针非常适合 CPU 调度。在启动时,检查 CPUID 并设置一些函数指针。稍后的函数通过函数指针调用,以获取调度程序为此主机选择的函数的任何版本。然后,在您想要使用具有可用优化版本的函数的任何地方,您都没有条件分支树。 x264(开源 h.264 视频编码器)将这种技术用于其广泛的 asm 例程集合。


您的 sse2 功能不应该超出 sse2 是对的,但是如果您将基线设置为 SSE2,您可以在任何地方使用它而无需检查。自动矢量化有时可以做一些好事。如果您使用浮点,您可以让 gcc 使用不同的 ABI,其中 float / double 在 SSE 寄存器中传递/返回,而不是 x87。 (或者可能仍然在堆栈上传递,就像过时的 32 位 x86 ABI 中的其他东西一样。)

过去约 10 年的所有 CPU 都可以运行 64 位代码,尽管有些人在较新 CPU 上的 CPU 上安装了 32 位 Windows。不幸的是,通常仍然需要为使用旧系统的人提供 32 位版本。

不过,SSE2 可能是基线的合理选择。以这种方式排除的最新 CPU 是第一代 AMD64 k8 内核之前的 AMD AthlonXP CPU。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2021-04-14
    相关资源
    最近更新 更多