Почему падает производительность при использовании SIMD (gcc, авто-векторизация)?
Пишу (для забавы) raytracer, все своими руками, включая векторные и матричные операции. Код линейной алгебры написал циклами. Вот пример выдержка для функции сложения векторов:
template
void add(const T* __restrict v, const T* __restrict u, T* __restrict o) {
align(v); align(u); align(o);
for (size_t i = 0; i < size; i++)
o_[i] = v_[i] + u_[i];
}
В общем все функции в таком ключе (надежда на -О3). Еще использовал ОpenMP (который сразу увеличил скорость в 4 раза, по числу ядер). А вот с SIMD проблема. Я не хотел использовать SIMD инструкции, (пусть компилятор этим занимается). Так вот если я использую векторы из 4 float (вместо трех), и в моем понимании должно работать быстрее, работает на самом деле в 3 раза медленнее. (аsm я не смотрел). Отмечу, что все данные alignas(16) и компилятор указывает, что "loop vectorized". Читал, что многие также сталкивались с неожиданными результатами авто векторизации.
Собственно, вопрос: у кого есть положительный опыт авто векторизации (gcc), без или в сочетании с OpenMP (#pragma omp simd)?
В общем тема не простая, я посмотрел asm, и выяснил (надо отметить слабое знание asm), что в некоторых случаях компилятор опримизирует так, что получается лучше, чем если писать самому используя simd инструцкии, так как он оптимизирует, не конкрентую процедуры а всю программу. Хотя вручную написанный на simd инструкциях код ведет себя более предсказуемо, разница +/- 30%. В общем, наверное для меня есть смысл просто попомогать компилятору с помошью alignas, -О3, -march=native, __restrict__ ну и писать попроще.