实际使用自动矢量化?

时间:2009-01-03 16:38:09

标签: gcc loops simd vector-processing

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

5 个答案:

答案 0 :(得分:5)

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

部分原因是保守 - 特别是当遇到可能的指针别名时,C / C ++编译器很难向自己“证明”矢量化是安全的,即使你是程序员知道的那样它是。大多数编译器(明智地)更喜欢不优化代码而不是冒错误编译的风险。这是高级语言比C更有优势的一个领域,至少在理论上是这样的(我在理论上说,因为我实际上并不知道任何自动向量化的ML或Haskell编译器)。

它的另一部分只是分析限制 - 我理解,大多数矢量化研究都与优化经典数值问题(流体动力学,比如说)相关,这是大多数矢量机器在几年前(当时)的面包和黄油。在CUDA / OpenCL,Altivec / SSE和STI Cell之间,各种形式的矢量编程在商业系统中得到广泛应用。)

编写标量处理器的代码很可能很容易被编译器进行矢量化。令人高兴的是,您可以做很多事情来使编译器更容易理解如何对其进行矢量化,例如循环平铺和部分循环展开,即使编译器没有弄清楚如何矢量化它。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

英特尔的Nehalem系列处理器(2008年末发布)实施了SSE 4.2指令,这些指令是SIMD指令。来源:wikipedia

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

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

基本上是这样的:

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