LINUX.ORG.RU

История изменений

Исправление 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 + ...
из-за округлений при сложении, и других ограничений типа double.

Но в целом, там ответы будут похожи, и так как при работе с дробными числами, нас всё равно интересует результат с некоторой погрешностью, то всё норм.

А -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 + ...
из-за округлений при сложении, и других ограничений типа double.

Но в целом, там ответы будут похожи, и так как при работе с дробными числами, нас всё равно интересует результат с некоторой погрешностью, то всё норм.

А -fast-math флаг, говорит компилятору, делай всё что угодно с оптимизациями, лишь бы это было правильно с точки зрения математики, а не с точки зрения получения точно такого же числа ответа, как и без оптимизаций.

Вот ещё пример, того что может сделать -fast-math, кроме изменения порядка при сложении. вместо

a/b;
использовать
a * 1/b; // 1/b вычислено на этапе компиляции