我经常使用基于编译器的矢量化,例如,用于AVX。我正在尝试通过依赖 C++11 对齐功能来提出一种更简洁的方法,而不依赖于基于编译器的扩展(例如英特尔的#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;
)。
谁是正确的?我的对齐方式有问题吗?有没有更好的方法来实现这一目标?
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];
}
这对我来说似乎是一个错误。您的语法完全正确,并被最新版本的GCC
和Clang
所接受。
首先,您当前使用的Intel C++ Compiler
版本很重要。
根据这份文件:
3.2 新增和更改的功能
C++ Composer XE 2015 现在包含英特尔®C++编译器 XE 15.0。这 此版本中新增或显著增强了以下功能:
- [...]
完整的 C++11 语言支持(包括 15.0 新增的这些功能)(/Qstd=c++11):
- 值类别 (N3055)
- 对齐和对齐 (N2341)
- decltype 扩展 (N3049, N3276)
- 继承构造函数 (N2540)
- 用户定义的文本 (N2765)
- thread_local (N2659)
首先,请注意列表中存在alignas
- 您可以从ICC 15.0
开始假设对这些功能的完全(或至少"与以前的版本相比有所改进")支持。其次,如果你问我,"新的或显着增强的">不等于"完全支持"。
此摘要还确认了此版本中对对齐要素的支持。
然而,它指出:
完整的 C++11 支持需要在 Linux 上使用 gcc 4.8 或更高版本的环境。
我也遇到了这个问题,这可能表明,并非一切都能正常工作。
正如@Simon所发现的那样,这是一个已确认的问题(或者更准确地说,缺乏支持)并已报告。跟踪器编号为DPD200361116。更多信息可以在此线程中找到。如果其他人会遇到此问题,我建议在此页面上跟踪更新,它们肯定会发布。