¿Qué tipo de optimizaciones hace la opción -ffast-math?

Vi que el tiempo necesario para que un algoritmo $ O (n ^ 2) $ simple se reduzca al de un algoritmo $ O (n) $ usando la opción.

Comentarios

  • Creo que esta pregunta ya tiene una respuesta en Stack Overflow: stackoverflow.com/questions/7420665/…
  • Yo ' estoy votando para cerrar esta pregunta como un duplicado de una pregunta en un diferente SE .
  • @BillBarth: Cerrar una pregunta como un duplicado generalmente solo funciona dentro de un sitio StackExchange determinado, con la excepción de publicaciones cruzadas obvias. Consulte meta.stackexchange.com/questions/172307/… en Meta StackExchange para conocer la discusión y las posibles soluciones.
  • @GeoffOxberry, lo vi y probé un plan B.
  • @BillBarth, ¿dónde crees que podría encontrar una respuesta elaborada?

Respuesta

Hay una respuesta canónica a esta pregunta en la wiki de GCC , que es presumiblemente mantenido, es con mucho la fuente de información más autorizada para este tipo de pregunta. Esta pregunta, por otro lado, puede eventualmente quedar desactualizada. Todo esto se explica con más detalle en la wiki, con ejemplos. Lo siguiente es esencialmente una cita de él para ilustrar cómo responde esta pregunta exacta, con comentarios menores:

  • -fno-signaling-nans
  • -fno-trapping-math

    El estándar IEEE recomienda que las implementaciones permitan a los manejadores de trampas manejar exc epciones como dividir por cero y desbordar. Esta bandera asume que no ocurrirá ninguna trampa visible para el uso.

  • -funsafe-math-optimizations – Estas optimizaciones rompen las leyes de la aritmética de punto flotante y pueden reemplazarlas con las leyes de la aritmética ordinaria de precisión infinita:

    Debido a errores de redondeo, el asociativo la ley del álgebra no es necesariamente válida para números de coma flotante y, por lo tanto, expresiones como (x + y) + z no son necesariamente iguales ax + (y + z).

  • -ffinite-math-only – Cantidades especiales como inf o nan nunca aparecerá, esto ahorra el tiempo que se dedica a buscarlos y manejarlos apropiadamente. Por ejemplo, ¿$ x – x $ siempre debe ser igual a $ 0.0 $?

  • -fno-errno-math

    desactiva la configuración de la variable errno como lo requiere C89 / C99 al llamar a las rutinas de la biblioteca matemática. Para Fortran, este es el valor predeterminado.

  • -fcx-limited-range

    hace que se omita el paso de reducción de rango al realizar una división compleja. Esto usa $ a / b = ((ar * br + ai * bi) / t) + i ((ai * br – ar * bi) / t) $ con $ t = br * br + bi * bi $ y podría no funciona bien en rangos arbitrarios de las entradas.

  • -fno-rounding-math

  • -fno-signed-zeros

    Debido a errores de redondeo, la ley asociativa del álgebra no es necesariamente válida para los números de coma flotante y, por lo tanto, expresiones como (x + y) + z no son necesariamente iguales ax + (y + z).

Estrictamente hablando, las implicaciones de los dos últimos no siempre son tan intuitivas como podría pensarse. Por ejemplo (ver wiki), ¿qué pasa con $ – (a – a) = a – a $, es $ + 0.0 $ o $ -0.0 $? Creo que hay bastante literatura sobre las implicaciones exactas, especialmente por Bill Kahan .

  • No mencionado directamente (yo ¿No lo ves?), pero con -ffast-math, ciertas funciones especiales comunes como el recíproco $ 1 / x $ y la raíz cuadrada $ \ sqrt {x} $ se reemplazan con menos Versiones precisas que son más rápidas, pero que aún tienen algunos niveles de error «tolerables» (en comparación con el error 0ulp requerido por el estándar) – aquí, por ejemplo, es lo que la precisión suele proporcionar libm de glibc . De hecho, esta es la causa más común de aceleración de -ffast-math, en un código que hace mucha aritmética con divisiones y raíces cuadradas, casi hasta el punto de que yo ( personalmente ) creo que las otras subopciones (-ffinite-math-only y similares especialmente: las NaN de señalización son bastante útiles para depurar) también muchos problemas en términos de costo / beneficio.

Vi que el tiempo que toma un simple $ O (n ^ 2) $ el algoritmo se reduce al de un algoritmo $ O (n) $ usando la opción.

Creo que esto es improbable y es posible que haya cometido un error en su análisis.Las optimizaciones de punto flotante inseguras pueden hacer que las expresiones individuales sean algo más baratas de evaluar en virtud de tener una mayor variedad de optimizaciones. Pero la aceleración siempre debe ser como mucho un factor constante. ¿Es posible que haya comparado un algoritmo $ O (n ^ 2) $ con un $ O (n) $ para $ n $ insuficientemente grandes?

Respuesta

Un algoritmo $ n ^ 2 $ puede reducirse a algo que se comporte $ O (n) $ si, por ejemplo, si el compilador conoce $ n $ y es un múltiplo del tamaño del vector para las instrucciones vectoriales (si las hay) admitidas por el procesador. Si el compilador puede ver todo esto, puede desenrollar un bucle interno y usar instrucciones vectoriales para hacer el trabajo. Esto puede reducir las operaciones generales realizadas a unas pocas y mejorar sustancialmente el rendimiento.

Mi lectura es que fast-math no habilita dicha optimización, pero podría hacerlo si están habilitadas implícitamente por unsafe-math-optimizations debido a restricciones de asociatividad que están deshabilitadas en el mismo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *