Что на самом деле делает математика gcc? - PullRequest
131 голосов
/ 14 сентября 2011

Я понимаю, что флаг gcc --ffast-math может значительно увеличить скорость операций с плавающей запятой и выходит за рамки стандартов IEEE, но я не могу найти информацию о том, что действительно происходит, когда он включен. Может ли кто-нибудь объяснить некоторые детали и, возможно, дать четкий пример того, как что-то изменится, если флаг будет включен или выключен?

Я пробовал копаться в S.O. на подобные вопросы, но не смог найти ничего, объясняющего работу математики.

Ответы [ 2 ]

221 голосов
/ 03 марта 2014

-ffast-math делает гораздо больше, чем просто нарушает строгое соответствие IEEE.

Прежде всего, конечно, оно нарушает строгое соответствие IEEE, что позволяет, например, переупорядочивать инструкции вчто-то, что математически то же самое (в идеале), но не совсем то же самое в плавающей точке.

Во-вторых, отключает установку errno после математических функций с одной инструкцией, что означает избегание записив локальную переменную потока (это может привести к разнице в 100% для этих функций на некоторых архитектурах).

В-третьих, предполагается, что вся математика конечна , что означает, что нетпроверки на NaN (или ноль) производятся там, где они будут иметь пагубные последствия.Просто предполагается, что этого не произойдет.

В-четвертых, он разрешает взаимные приближения для деления и обратного квадратного корня.

Кроме того, он отключает нулевой знак(код предполагает, что нулевой знак не существует, даже если цель поддерживает его) и математика округления, которая позволяет, среди прочего, выполнять постоянное свертывание во время компиляции.

Наконец, он генерирует код, который предполагает, что никакие аппаратные прерывания не могутпроисходят из-за математики сигнализации / захвата (то есть, если они не могут быть отключены на целевой архитектуре и, следовательно, действительно происходят , они не будут обрабатываться).

72 голосов
/ 14 сентября 2011

Как вы упомянули, он допускает оптимизации, которые не сохраняют строгое соответствие IEEE.

Пример таков:

x = x*x*x*x*x*x*x*x;

до

x *= x;
x *= x;
x *= x;

Поскольку плавающийарифметика с точками не является ассоциативной, упорядочение и факторинг операций влияют на результаты из-за округления.Следовательно, эта оптимизация не выполняется при строгом поведении FP.

На самом деле я не проверял, выполняет ли GCC именно эту оптимизацию.Но идея та же.

...