自动矢量化的实际使用?

Posted

技术标签:

【中文标题】自动矢量化的实际使用?【英文标题】:Practical use of automatic vectorization? 【发布时间】:2009-01-03 16:38:08 【问题描述】:

有没有人利用 gcc 的自动矢量化功能?在现实世界中(与示例代码相反)?是否需要重组现有代码才能利用?在任何生产代码中是否有大量案例可以通过这种方式矢量化?

【问题讨论】:

【参考方案1】:

我还没有看到 GCC 或 Intel C++ 自动对除了非常简单的循环之外的任何东西进行矢量化,即使给出可以(并且在我使用 SSE 内在函数手动重写它们之后)可以被矢量化的算法代码。

这部分是保守的——尤其是在面对可能的指针别名时,C/C++ 编译器很难向自己“证明”向量化是安全的,即使你作为程序员知道这一点它是。大多数编译器(明智地)宁愿不优化代码,也不愿冒错误编译的风险。至少在理论上,这是高级语言比 C 具有真正优势的一个领域(我说理论上是因为我实际上并不知道任何自动向量化 ML 或 Haskell 编译器)。

另一部分只是分析限制——据我所知,大多数向量化研究都与优化经典数值问题(比如流体动力学)有关,这是几年前大多数向量机的基础(当时,在 CUDA/OpenCL、Altivec/SSE 和 STI Cell 之间,各种形式的向量编程在商业系统中变得广泛可用)。

考虑到为标量处理器编写的代码不太可能很容易被编译器向量化。令人高兴的是,您可以做很多事情来使编译器更容易理解如何对其进行矢量化,例如循环平铺和部分循环展开,即使编译器不知道如何处理,也(倾向于)提高现代处理器的性能矢量化它。

【讨论】:

【参考方案2】:

很难在任何业务逻辑中使用,但是当您以相同的方式处理大量数据时会加快速度。

很好的例子是声音/视频处理,您对每个样本/像素应用相同的操作。 我已经为此使用了 VisualDSP,您必须在编译后检查结果 - 如果它真的在应该使用的地方使用。

【讨论】:

【参考方案3】:

向量化将主要用于数值程序。矢量化程序可以在矢量处理器上运行得更快,例如 PS3 游戏机中使用的 STI 单元处理器。在那里,用于渲染游戏图形的数值计算可以通过矢量化大大加快。这种处理器称为 SIMD(单指令多数据)处理器。

在其他处理器上不会使用矢量化。矢量化程序在不适用于非 SIMD 处理器的矢量化指令集上运行。

英特尔的 Nehalem 系列处理器(2008 年底发布)实现 SSE 4.2 指令,即 SIMD 指令。来源:wikipedia。

【讨论】:

@Amit,当今许多现代 CPU 都配备了矢量处理器。这些向量处理器可以通过特殊指令访问。有时,当给定适当的标志和一组明显有限的可矢量化代码时,GCC 可以发出这些指令。【参考方案4】:

矢量化指令不仅限于 Cell 处理器 - 大多数现代工作站之类的 CPU 都有它们(PPC、x86 自 pentium 3、Sparc 等...)。当用于浮点运算时,它可以为计算密集型任务(过滤器等)提供很大帮助。根据我的经验,自动矢量化效果并不好。

【讨论】:

x86 自 Pentium MMX 和 AMD 的 K6-2 和 3DNow。比 P3 早得多。【参考方案5】:

您可能已经注意到,实际上几乎没有人知道如何充分利用 GCC 的自动矢量化。如果您在网上搜索人们的 cmets,总是会想到 GCC 允许您启用自动矢量化,但它很少实际使用它,因此如果您想使用 SIMD 加速(例如:MMX, SSE、AVX、NEON、AltiVec),那么您基本上必须弄清楚如何使用编译器内在函数或汇编语言代码来编写它。

但是内在函数的问题在于,您实际上需要理解它的汇编语言方面,然后还要学习描述您想要的内容的内在方法,这可能会导致代码效率低于您编写的代码汇编代码(例如 10 倍),因为编译器仍然无法很好地利用您的内在指令!

例如,您可能正在使用 SIMD Intrinsics,以便可以同时并行执行许多操作,但您的编译器可能会生成汇编代码,在 SIMD 寄存器和普通 CPU 寄存器之间来回传输数据,有效地使您的 SIMD 代码以与普通代码相似的速度(甚至更慢)运行!

所以基本上:

如果您想要 100% 的加速(2x 速度),然后要么买 官方 Intel/ARM 编译器或将您的部分代码转换为使用 SIMD C/C++ Intrinsics。 如果你 想要 1000% 的加速(10 倍速度),然后 手动使用 SIMD 指令将其编写为汇编代码。或者,如果在您的硬件上可用,请改用 GPU 加速,例如 OpenCL 或 Nvidia 的 CUDA SDK,因为它们可以在 GPU 中提供与 SIMD 在 CPU 中类似的加速。

【讨论】:

以上是关于自动矢量化的实际使用?的主要内容,如果未能解决你的问题,请参考以下文章

GCC 自动矢量化对运行时没有影响,即使在所谓“有利可图”的情况下也是如此

使用 GCC 强制自动矢量化

ArcScan自动矢量化

为啥库需要硬编码矢量化而不是编译器自动矢量化

自动矢量化比较

如何在 Microsoft Visual Studio 2017 或 2019 中启用或使用自动矢量化以及自动并行化?