История изменений
Исправление fsb4000, (текущая версия) :
Но если добавить -fast-math ... в ассемблерном выхлопе появились всякие vmovss и прочие....
Я это давно узнал, поэтому и компилирую с -fast-math , и юнит тесты тоже чтобы не сломалось.
Причина по которой, без -fast-math не включаются векторизация в следующем.
по умолчанию сложение работает так:
a1+a2+a3+a4... // последовательно
При векторизации так:
a1 + a5 + a9
a2 + a6 + a10
a3 + a7 + a11
a4 + a8 + a12
// потом складываются частичные суммы
// и добавляются остаточные слагаемые, если количество слагаемых не кратно 4
Но с точки зрения типа double это разное
a1 + a5 + a9 +...+a2 +...
a1+a2+a3+a4 + ...
Но в целом, там ответы будут похожи, и так как при работе с дробными числами, нас всё равно интересует результат с некоторой погрешностью, то всё норм.
А -fast-math флаг, говорит компилятору, делай всё что угодно с оптимизациями, лишь бы это было правильно с точки зрения математики, а не с точки зрения получения точно такого же числа ответа, как и без оптимизаций.
Вот ещё пример, того что может сделать -fast-math, кроме изменения порядка при сложении. вместо
a/b; // a - переменная, b - константа
a * 1/b; // 1/b вычислено на этапе компиляции
Исходная версия fsb4000, :
Но если добавить -fast-math ... в ассемблерном выхлопе появились всякие vmovss и прочие....
Я это давно узнал, поэтому и компилирую с -fast-math , и юнит тесты тоже чтобы не сломалось.
Причина по которой, без -fast-math не включаются векторизация в следующем.
по умолчанию сложение работает так:
a1+a2+a3+a4... // последовательно
При векторизации так:
a1 + a5 + a9
a2 + a6 + a10
a3 + a7 + a11
a4 + a8 + a12
// потом складываются частичные суммы
// и добавляются остаточные слагаемые, если количество слагаемых не кратно 4
Но с точки зрения типа double это разное
a1 + a5 + a9 +...+a2 +...
a1+a2+a3+a4 + ...
Но в целом, там ответы будут похожи, и так как при работе с дробными числами, нас всё равно интересует результат с некоторой погрешностью, то всё норм.
А -fast-math флаг, говорит компилятору, делай всё что угодно с оптимизациями, лишь бы это было правильно с точки зрения математики, а не с точки зрения получения точно такого же числа ответа, как и без оптимизаций.
Вот ещё пример, того что может сделать -fast-math, кроме изменения порядка при сложении. вместо
a/b;
a * 1/b; // 1/b вычислено на этапе компиляции