如何克服icc中的“存在向量依赖”

Posted

技术标签:

【中文标题】如何克服icc中的“存在向量依赖”【英文标题】:How to overcome "existence of vector dependence" in icc 【发布时间】:2013-07-26 05:12:42 【问题描述】:

我想在 C 中矢量化以下循环:

for(k = 0; k < SysData->numOfClaGen; k++)
            A[k] = B[k] * cos(x1[2 * k] - x1[ind0 + k]);

其中,变量之间没有别名,ind0 是一个常量。没有其他指针(AB)指向 ind0,因此,ind0 在整个循环中保持不变。

当我用 icc 编译代码时,它说这个循环不能被矢量化,因为可能存在矢量依赖性。这是消息:

loop was not vectorized: existence of vector dependence.

我缩小了问题范围,发现用常数替换 ind0 可以解决问题。所以,我假设 icc 认为A 可能指向ind0,因此ind0 可能会改变。

我想知道如何帮助编译器知道向量化这样的循环是安全的。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

在 for 循环前面添加#pragma ivdep,它指示编译器忽略假定的向量依赖关系。

#pragma ivdep
for(k = 0; k < SysData->numOfClaGen; k++)
            A[k] = B[k] * cos(x1[2 * k] - x1[ind0 + k]);

有关 ivdep 的更多信息,请参阅icc doc

【讨论】:

【参考方案2】:

对指针使用restrict 修饰符向编译器断言没有别名。这个关键字是在 C99 中引入的。 C++ 不支持它,但许多 C++ 编译器支持 __restrict 作为等效的专有扩展。对于英特尔编译器,必须通过添加命令行标志-restrict (Linux) 或/Qrestrict (Windows) 来启用restrict。在您的代码的以下版本中,当使用英特尔编译器版本 13.1.3.198 时,循环会根据需要进行矢量化:

#include <math.h>

struct bar 
    int numOfClaGen;
;

void foo (double * restrict A, 
          const double * restrict B,
          const double * restrict x1,
          const struct bar * restrict SysData,
          const int ind0)

    int k;
    for (k = 0; k < SysData->numOfClaGen; k++) 
        A[k] = B[k] * cos(x1[2 * k] - x1[ind0 + k]);
    

如下调用编译器(在 64 位 Windows 系统上)

icl /c /Ox /QxHost /Qrestrict /Qvec-report2 vectorize.c

编译器报告

vectorize.c(14): (col. 5) remark: LOOP WAS VECTORIZED.

【讨论】:

【参考方案3】:

icc 在一年前更改为将 -ansi-alias 设置为 linux 和 Mac 的默认值。对于 Windows,不能指望此默认设置,因为它与 Microsoft 的使用相冲突。此选项等效于 gcc -fstrict-aliasing,自 gcc 3.0 以来一直是默认选项。我认为对于这样一个有限的问题,设置此选项比设置 ivdep restrict 或 simd 要好得多。 尽管没有很好的文档记录,但 icc 将 __restrict 视为与 gcc 相同,并且不需要限制或 C99 选项来接受它。原则上,它应该只对正在修改的对象起作用(上例中的 A[])。 奇怪的是,__restrict 对于 MSVC++ 的含义略有不同。它允许非向量优化,否则可能会被可能的依赖项阻止,但不能启用向量化(但它可能适用于当前情况)。

【讨论】:

以上是关于如何克服icc中的“存在向量依赖”的主要内容,如果未能解决你的问题,请参考以下文章

ICC 程序集输出中的所有这些数字是啥意思?

icc2怎么打开数据

如何在 iPad/iPhone 上使用 ICC 配置文件?

如何强制 OpenMPI 使用 GCC 而不是 ICC?是不是需要重新编译 OpenMPI?

未检测到设备时如何着色以安装 ICC 配置文件?

如何通过读卡器使用Java激活/开启ICC卡?