指向对齐内存的指针
Pointer to aligned memory
我经常使用基于编译器的矢量化,例如,用于 AVX。我试图通过依赖 C++11 对齐功能来提出一种更简洁的方法,而不依赖于基于编译器的扩展(例如英特尔的 #pragma vector aligned
)。如果你考虑下面的代码,例如,aligned::array<double,48> my_array;
允许我在堆栈中声明一个正确对齐的数组,如果它用于相同的翻译单元,编译器似乎可以识别这一点。
我现在的问题是如何声明一个参数对齐的函数。我最成功的尝试是,例如,aligned::ptr<double>
,在下面的函数 f()
中使用。
gcc
在没有警告的情况下编译它(使用 -std=c++0x -O3
),并且循环被向量化。然而,Intel 的 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];
}
对我来说这似乎是一个错误。您的语法完全正确,并被最新版本的 GCC
和 Clang
.
接受
首先,重要的是您当前使用的 Intel C++ Compiler
版本。
3.2 New and Changed Features
C++ Composer XE 2015 now contains Intel® C++ Compiler XE 15.0. The
following features are new or significantly enhanced in this version:
- [...]
Full C++11 language support (includes these feature new to 15.0) (/Qstd=c++11):
- value categories (N3055)
- alignas and alignof (N2341)
- decltype extensions (N3049, N3276)
- inheriting constructors (N2540)
- user defined literals (N2765)
- thread_local (N2659)
首先,请注意列表中存在 alignas
- 您可以假设完全(或至少 "improved comparing with previous version")支持这些功能从 ICC 15.0
开始。其次,"new or significantly enhanced"不等于"fully supported",如果你问我
This summary 也确认此版本支持对齐功能。
然而,它指出:
Full C++11 support requires gcc 4.8 environment or newer on Linux.
我也遇到了 this,这可能表明,并非一切正常。
正如@Simon 所发现的,这是一个已确认的问题(或者更准确地说,是缺乏支持)并且已被报告。跟踪器编号为 DPD200361116。可以找到更多信息 in this thread。如果其他人遇到这个问题,我建议跟踪此页面上的更新,他们肯定会发布。
我经常使用基于编译器的矢量化,例如,用于 AVX。我试图通过依赖 C++11 对齐功能来提出一种更简洁的方法,而不依赖于基于编译器的扩展(例如英特尔的 #pragma vector aligned
)。如果你考虑下面的代码,例如,aligned::array<double,48> my_array;
允许我在堆栈中声明一个正确对齐的数组,如果它用于相同的翻译单元,编译器似乎可以识别这一点。
我现在的问题是如何声明一个参数对齐的函数。我最成功的尝试是,例如,aligned::ptr<double>
,在下面的函数 f()
中使用。
gcc
在没有警告的情况下编译它(使用 -std=c++0x -O3
),并且循环被向量化。然而,Intel 的 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];
}
对我来说这似乎是一个错误。您的语法完全正确,并被最新版本的 GCC
和 Clang
.
首先,重要的是您当前使用的 Intel C++ Compiler
版本。
3.2 New and Changed Features
C++ Composer XE 2015 now contains Intel® C++ Compiler XE 15.0. The following features are new or significantly enhanced in this version:
- [...]
Full C++11 language support (includes these feature new to 15.0) (/Qstd=c++11):
- value categories (N3055)
- alignas and alignof (N2341)
- decltype extensions (N3049, N3276)
- inheriting constructors (N2540)
- user defined literals (N2765)
- thread_local (N2659)
首先,请注意列表中存在 alignas
- 您可以假设完全(或至少 "improved comparing with previous version")支持这些功能从 ICC 15.0
开始。其次,"new or significantly enhanced"不等于"fully supported",如果你问我
This summary 也确认此版本支持对齐功能。
然而,它指出:
Full C++11 support requires gcc 4.8 environment or newer on Linux.
我也遇到了 this,这可能表明,并非一切正常。
正如@Simon 所发现的,这是一个已确认的问题(或者更准确地说,是缺乏支持)并且已被报告。跟踪器编号为 DPD200361116。可以找到更多信息 in this thread。如果其他人遇到这个问题,我建议跟踪此页面上的更新,他们肯定会发布。