Que fait réellement ffast-math de gcc?

je comprends que le drapeau --ffast-math de gcc peut considérablement augmenter la vitesse pour les opérations sur flotteurs, et va au-delà des normes de L'IEEE, mais je ne semble pas trouver d'informations sur ce qui se passe vraiment quand il est allumé. Quelqu'un peut-il expliquer certains détails et peut-être donner un exemple clair de la façon dont quelque chose allait changer si l'indicateur est allumé ou éteint?

j'ai essayé de creuser par S. O. pour des questions similaires, mais je n'ai rien trouvé expliquant le fonctionnement de ffast-math.

115
demandé sur einpoklum 2011-09-14 21:45:30

2 réponses

comme vous l'avez mentionné, il permet des optimisations qui ne préservent pas la stricte conformité IEEE.

un exemple est celui-ci:

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

à

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

parce que l'arithmétique à virgule flottante n'est pas associative, l'ordre et la factorisation des opérations affecteront les résultats dus à l'arrondi. Par conséquent, cette optimisation n'est pas faite sous un comportement strict de FP.

Je n'ai pas encore vérifié voir si GCC fait réellement cette optimisation particulière. Mais l'idée est la même.

58
répondu Mysticial 2018-08-31 13:29:08

-ffast-math fait beaucoup plus que simplement briser la stricte conformité IEEE.

tout d'abord, bien sûr, il ne casse conformité stricte IEEE, permettant par exemple la réorganisation des instructions à quelque chose qui est mathématiquement le même (idéalement) mais pas exactement le même en virgule flottante.

Deuxièmement, il désactive réglage errno après instruction unique de fonctions mathématiques, ce qui signifie éviter d'écrire à une variable thread-local (cela peut faire une différence de 100% pour ces fonctions sur certaines architectures).

troisièmement , il fait l'hypothèse que toutes les mathématiques est fini , ce qui signifie qu'aucun contrôle pour NaN (ou zéro) sont faites en place où ils auraient des effets néfastes. Il est simplement supposé que cela n'arrivera pas.

quatrièmement, il permet approximations réciproques pour division et racine carrée réciproque.

de plus, il désactive le zéro signé (le code suppose que le zéro signé n'existe pas, même si la cible le supporte) et l'arrondi mathématique, ce qui permet entre autres un pliage constant au moment de la compilation.

enfin, il génère du code qui suppose qu'aucune interruption de matériel ne peut se produire en raison de la signalisation/piégeage mathématiques (c'est-à-dire, si ceux-ci ne peuvent pas être désactivés sur l'architecture cible et par conséquent se produisent , ils ne seront pas traités).

193
répondu Damon 2014-03-03 00:15:58