我经常使用基于编译器的矢量化,例如,用于AVX。我试图通过依赖C ++ 11对齐功能,在不依赖基于编译器的扩展(例如Intel #pragma vector aligned
)的情况下提出一种更清晰的方法。如果您考虑下面的代码,例如,aligned::array<double,48> my_array;
允许我在堆栈中声明一个具有正确对齐的数组,并且如果它在相同的转换单元中使用,则编译器似乎认识到这一点。
我现在的问题是如何声明具有对齐参数的函数。我最成功的尝试是,例如aligned::ptr<double>
,在下面的函数f()
中使用。
gcc
在没有警告的情况下编译它(使用-std=c++0x -O3
),循环被矢量化。但是,英特尔icc
会发出警告,并且无法正确向量化(warning #3463: alignas does not apply here; using type alignas(64) = T;
)。
谁是对的?我使用alignas有什么问题吗?有没有更好的方法来实现这一目标?
namespace aligned {
template <class T, int N>
using array alignas(64) = T[N];
template <class T>
using type alignas(64) = T;
template <class T>
using ptr = type<T> *;
}
#ifdef __ICC
#define IVDEP "ivdep"
#else
#define IVDEP "GCC ivdep"
#endif
void f(aligned::ptr<double> x, const aligned::ptr<double> y) {
_Pragma(IVDEP)
for(int i=0; i<4; i++)
x[i] = x[i]*y[i];
}
答案 0 :(得分:4)
这对我来说似乎是个错误。您的语法完全正确,并被GCC
和Clang
的最新版本接受。
首先,您目前使用的Intel C++ Compiler
版本很重要。
3.2新功能和更改功能
C ++ Composer XE 2015现在包含英特尔®C++编译器XE 15.0。该 以下功能在此版本中是新的或显着增强的:
- [...]
完整的C ++ 11语言支持(包括15.0的新功能)(/ Qstd = c ++ 11):
- 价值类别(N3055)
- alignas and alignof(N2341)
- decltype扩展名(N3049,N3276)
- 继承构造函数(N2540)
- 用户定义的文字(N2765)
- thread_local(N2659)
首先,请注意列表中是否存在alignas
- 您可以从{{{}}开始假设完全(或至少“与先前版本相比改进了)对这些功能的支持{1}}。其次,如果你问我,“新的或显着增强的”不等于“完全支持”。
This summary也确认了此版本中对齐功能的支持。
然而,它注意到:完整的C ++ 11支持需要gcc 4.8环境或更新的Linux。
我也遇到了this,这可能表明,并非一切都正常。
正如@Simon已经发现的那样,这是一个已确认的问题(或更确切地说,缺乏支持),并且已有报道。跟踪器编号 DPD200361116 。可以找到更多信息in this thread。如果其他人遇到此问题,我建议您跟踪此页面上的更新,这些内容肯定会发布。