我可以将 SIMD 内在函数用于在云上运行的软件吗?

Posted

技术标签:

【中文标题】我可以将 SIMD 内在函数用于在云上运行的软件吗?【英文标题】:Can I use SIMD intrinsics for software that runs on cloud? 【发布时间】:2019-02-15 23:58:27 【问题描述】:

只是考虑将某些软件迁移到云端时必须执行的操作。 该软件使用从 SSE3 到 AVX 的大量 SIMD 内部函数(英特尔的)。它在本地服务器上运行良好。 我想知道应该做什么样的改变才能将它迁移到云端。 当然希望能够使用更改尽可能少的 SIMD 功能。 但是,似乎无法预测在云上运行时将使用哪种 CPU。当软件在某种虚拟机或容器上运行时,我怀疑是否可以使用特定 CPU 的低级功能。

【问题讨论】:

【参考方案1】:

是的,在云服务器上使用 SIMD 比在您要分发到人们桌面的应用程序中更容易,因为您通常可以更多控制代码将在哪些硬件上运行。 (取决于哪个云托管,您可以非常准确地知道,就像在您当前的私有服务器上运行一样。)


在虚拟机中,您编译的可执行文件中的机器代码仍然在(通常)x86 CPU 上本地运行,通常是 Intel Xeon,但也可能是 AMD 服务器。

某些 VM 软件可能设置为不暴露 AVX,但任何 x86 云主机都至少有 SSE4.2。 SSE2 是 x86-64 的基准,因此不能公开它不是一个选项。 CPU 太旧以至于只有 SSE4.1 或 SSSE3 可能早就退役了,因为不值得运行它们。

大多数虚拟机/云托管缺少的主要内容是硬件性能计数器。因此,您将很难为使用 Linux perf record 或 @987654322 的云服务器进行性能分析@ 用于任何事件,例如缓存未命中,甚至循环。 perf 可能有一些基于时间的采样,并且其他分析工具是为基于时间的采样而设计的,而不是硬件性能计数器。


例如,Google Cloud 计算服务器可让您选择运行实例的硬件类型,例如Haswell 或 Skylake-X。使用其中任何一个,您都可以使用 AVX2 和 FMA。 (以及 BMI2、popcnt 等)。使用 Skylake-X,您还可以拥有 AVX512BW / AVX512DQ / 其他一些 AVX512 口味。酌情使用clang/gcc -O3 -march=skylake-avx512-march=haswell 进行编译。

如果能够假设 AVX+FMA 对您的软件很重要,我假设其他云主机具有类似的机制,可以让您至少选择 ISA 扩展的最低基线集。我希望至少非常很容易找到 AVX,并且可能也很容易找到 Haswell。 (AVX2 + FMA + BMI1/BMI2)。 -march=haswell 是一个有用的基线编译目标。

虚拟机支持在物理机之间迁移虚拟机,但它们永远不会迁移到会删除来宾开始使用的某些功能的主机。 (这是不通过 AVX 或宣传与 CPU 一样最新的 SSE 或 AVX 版本的原因之一。)

AVX 和 AVX512 添加了新的架构状态(新的/更宽的寄存器),因此需要对上下文切换提供新的保存/恢复支持。如果 OS/VM 在控制寄存器中没有设置正确的位,AVX 指令就会出错。因此,VM 可以完全阻止来宾使用 AVX。但是由于必须启用 SSE2,如果硬件支持,他们无法阻止您使用 SSE4.2。可能会设置来宾虚拟机,因此 CPUID 仅宣传 SSE2 但不会更高,但它们不能在 SSE2 指令工作时使 SSE4.2 指令出错。 AVX2+FMA 也一样:如果启用了 AVX1,只有真正不支持 AVX2 或 FMA 的底层 CPU 才会使它们出错,而不是 CPUID 人为限制。但不宣传 FMA 可能意味着您的 VM 可以随时迁移到不支持它的硬件。


英特尔仍在其 Silvermont / Goldmont 产品线中生产没有 AVX 的 CPU。其中一些用于低功耗服务器,但我认为这对于大多数云计算来说是罕见的。 (英特尔还销售不带 AVX 的 Skylake Celeron/Pentium CPU,但在云主机中找不到。)

除此之外,Sandybridge 大约在 2011 年推出,AMD 大约在同一时间推出了 Bulldozer。因此,任何在物理上缺乏 AVX 支持的主流 CPU 都已过时,而且对于大多数主机来说,它们的内存带宽和 CPU 能力都不值得支付电费。

【讨论】:

以上是关于我可以将 SIMD 内在函数用于在云上运行的软件吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用内在函数加速类型转换吗?

与 SIMD 内在函数进行比较和交换

Cython 和 SIMD 内在函数:防止 SIMD 内在函数的参数转换为 python 对象

如何在 ARM NEON SIMD 内在函数上编写“a[i]=b[c[i]]”

如何在云上拥有软件访问文件

是否有用于元素部分移位的 simd 指令/内在/内置?