Вот SSCCE:
class Vec final {
public:
float data[4];
inline Vec(void) {}
inline ~Vec(void) {}
};
Vec operator*(float const& scalar, Vec const& vec) {
Vec result;
#if 1
for (int k=0;k<4;++k) result.data[k]=scalar*vec.data[k];
#else
float const*__restrict src = vec.data;
float *__restrict dst = result.data;
for (int k=0;k<4;++k) dst[k]=scalar*src[k];
#endif
return result;
}
int main(int /*argc*/, char* /*argv*/[]) {
Vec vec;
Vec scaledf = 2.0f * vec;
return 0;
}
При компиляции MSVC 2013 сообщает мне (/Qvec-report:2
), что
main.cpp(11): информация C5002: цикл не векторизован по причине "1200"
Это означает, что "[l] oop содержит зависящие от цикла данные зависимостей".
Я заметил, что комментирование конструктора или деструктора для Vec
(редактирование: или по умолчанию их, например, Vec()=default;
) заставляет его успешно векторизовать. Мой вопрос: почему?
Примечание. Переключение #if
также заставит его работать. Важно __restrict
.
Примечание. Изменение float const& scalar
на float const scalar
приводит к тому, что векторизация сообщает 1303
(векторизация не будет выигрышной), я подозреваю, потому что эта ссылка может быть передана непосредственно в регистр SSE, тогда как значение pass-by-value нуждается в другом копия.