Я часто использую векторизацию на основе компилятора, например, для AVX. Я пытаюсь найти более чистый способ, не полагаясь на расширения на основе компилятора (например, Intel #pragma vector aligned
), полагаясь на возможности выравнивания С++ 11. Если вы рассмотрите приведенный ниже код, например, 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];
}