【问题标题】:Intel compiler cannot vectorize this simple loop?英特尔编译器无法向量化这个简单的循环?
【发布时间】:2013-04-30 09:53:58
【问题描述】:

所以我有以下对我来说似乎很简单的代码:

#define MODS_COUNT 5

int start1 = <calc at runtime>;
int start2 = <calc at runtime>;

for (int j=0; j<MODS_COUNT; j++) // loop 5 times doing simple addition.
    logModifiers[start1 +  j] += logModsThis[start2 + j];

这个循环是外循环的一部分(不确定这是否会有所不同)

编译器说: message : loop was not vectorized: vectorization possible but seems inefficient.

为什么这个循环不能被矢量化?这对我来说似乎很简单。如何强制矢量化并自己检查性能?

我有英特尔 C++ 编译器 2013 更新 3。

如果有人感兴趣,这里有完整的代码:http://pastebin.com/Z6H5ZejW

编辑:我知道编译器认为它效率低下。我在问:

为什么效率低?

我怎样才能强制它,以便我可以对自己进行基准测试?

Edit2:如果我将其更改为 4 而不是 5,那么它将被矢量化。是什么让 5 效率低下?我认为它可以在 2 条指令中完成,第 4 条指令,第二条是“正常”的 1 条指令,而不是 5 条指令。

【问题讨论】:

  • 你的意思是说你认为编译器是错误的“似乎效率低下”?我倾向于同意,5 个项目的循环可能不会非常有效地矢量化。
  • 编译器不会告诉你循环不能被向量化。就我个人而言,我认为选择(不)服从程序员(编译器)认为合适的编译器可能是一个非常好的主意。
  • 很可能数据在内存中的组织方式不适合在其上直接使用向量指令,并且编译器已确定重新排列数据的成本超过通过操作节省的时间同时更多。
  • 尝试67 次。
  • @Koushik 6 和 7 不矢量化。 4 和 8 可以。

标签: c++ vectorization


【解决方案1】:

根据英特尔编译器中的向量化:

有 128 字节长的 SIMD(单指令多数据)寄存器。因此,如果 sizeof(int) 为 4,则 4 整数可以位于这些寄存器中,并且单个指令可以在这些 4 ints 上执行。(这也取决于是否对这些 @ 执行相同类型的操作987654326@s,这里是真的。LHS 上数组的每个元素都依赖于不同数组的不同元素。)

如果有 8 个ints,则需要两条指令。(而不是没有矢量化的 8 个)。

但如果有 5(或 6 或 7)个ints,那么这也需要两条指令。其中might 并不比没有矢量化代码更好。

进一步阅读LINK

【讨论】:

  • 为什么5个循环的两条指令不是更好? 2条指令不是比5条快吗?
  • @Spacemonkey 但是5号的计算不需要SIMD寄存器。与在没有矢量化的情况下计算所有这些(如果 5 被矢量化)相比,这可能更重。要小心,英特尔并没有说矢量执行所需的时间不是没有矢量化的1/4 次。它只是说 1 条指令。
  • 对你的代码进行基准测试(用这么小的循环)将是一个挑战。循环计数太高,编译器直接将其向量化。太小将难以区分。
  • 如果循环计数大小 = 1024,则 当指定 SSE2 或更高版本的指令集时,一个好的编译器将通过使用向量运算来优化此循环。该代码将 b 的四个元素读入一个 128 位向量寄存器,与另一个包含 (2,2,2,2) 的向量寄存器进行加法运算,并将四个结果存储在 a 中。然后,此操作将重复 1024/4 = 256 次,在最佳情况下速度将提高 4 倍。最好是循环计数可被每个向量的元素数整除。 *(来自 *Optimizing software in C++ An optimization guide 作者:Agner Fog。)
  • @SChepurin 是的,但是在这个特定的代码中,我们谈论的是一个非常小的计数,这很有趣。每个周期都很重要。顺便说一句,最好知道在 SIMD 寄存器上执行需要多少个周期。这将消除围绕这个问题的所有疑虑。
【解决方案2】:

要使矢量化有意义,最内部的循环必须有足够大的行程计数。在您的情况下,它很小,编译器会根据其成本模型计算出矢量化带来的加速会很小,或者是负数。

我曾见过奇迹何时进行循环交换 - 交换了内循环和外循环,这样最内循环的行程数就大了。

【讨论】:

    猜你喜欢
    • 2018-08-17
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多