9

Antecedentes: Hace¿Existe un g ++ (Linux) equivalente a/fp: precise y/fp: flags rápidos utilizados en Visual Studio?

muchos años, heredó una base de código que estaba utilizando la (VC++) flag '/ fp: rápido' Visual Studio para producir un código más rápido en una biblioteca de cálculo pesado en particular. Desafortunadamente, '/ fp: fast' produjo resultados ligeramente diferentes a la misma biblioteca bajo un compilador diferente (Borland C++). Como necesitábamos producir exactamente los mismos resultados, cambié a '/ fp: precise', que funcionó bien y desde entonces todo ha sido color de rosa. Sin embargo, ahora estoy compilando la misma biblioteca con g ++ en uBuntu Linux 10.04 y veo un comportamiento similar, y me pregunto si podría tener una causa similar. Los resultados numéricos de mi compilación de g ++ son ligeramente diferentes de los resultados numéricos de mi compilación de VC++. Esto me lleva a mi pregunta:

Pregunta:

¿Tiene g ++ tener parámetros equivalentes o similares a la 'FP: rápido' y 'FP: precisas' opciones en VC++? (? Y ¿qué es esto que quiero para activar el 'fp: precisa'. Equivalente)

más detallado de la información:

puedo compilar usando 'hacer', que llama g ++. Por lo que puedo decir (los archivos make son un poco crípticos, y no fueron escritos por mí) los únicos parámetros agregados a la llamada g ++ son los "normales" (incluyen las carpetas y los archivos para compilar) y -fPIC (No estoy seguro de lo que hace este cambio, no lo veo en la página 'hombre').

Los únicos parámetros relevantes en 'man g ++' parecen ser activar las opciones de optimización. (por ejemplo, optimizaciones de seguridad-matemáticas). Sin embargo, no creo que encienda nada, solo quiero desactivar la optimización relevante.

Probé versiones de Release y Debug, VC++ da los mismos resultados para release y debug, y g ++ da los mismos resultados para release y depuración, pero no puedo obtener la misma versión que la versión de g ++ Versión VC++.

+0

Encontré el significado de -fPIC después de un poco más de google: -fPIC Si es compatible con la máquina de destino, emita código independiente de posición, adecuado para enlaces dinámicos, incluso si (3, n) ramas necesitan grandes desplazamientos. – Boinst

+0

Esto puede consumir mucho tiempo, pero vale la pena el esfuerzo: ¿puedes intentar señalar la instrucción más antigua (o al menos la línea de código) donde algunos cálculos divergen entre MSVC y gcc? –

+0

Sí, estoy trabajando en su sugerencia. Desafortunadamente, estoy un poco en Linux n00b, ¡así que me lleva algo de tiempo reunir todo! – Boinst

Respuesta

9

El exceso de precisión de registro es un problema solo en los registros de FPU, que los compiladores (con los interruptores de habilitación adecuados) tienden a evitar de todos modos. Cuando los cálculos de punto flotante se llevan a cabo en registros SSE, la precisión del registro es igual a la memoria uno.

En mi experiencia, la mayor parte del/fp: impacto rápido (y posible discrepancia) proviene del compilador que se toma la libertad de realizar transformaciones algebraicas. Esto puede ser tan simple como cambiar sumandos orden:

(a + b) + c --> a + (b + c) 

puede ser - la distribución de multiplicaciones como un * (b + c) a voluntad, y puede llegar a algunas bastante complejas transformaciones - todo con la intención de reutilizar los cálculos anteriores. Con una precisión infinita, tales transformaciones son benignas, por supuesto, pero en precisión finita realmente cambian el resultado. Como un ejemplo de juguete, pruebe el summand-order-example con a = b = 2^(- 23), c = 1. MS's Eric Fleegal describes it in much more detail.

En este sentido, el conmutador gcc más cercano a/fp: precise -fno-unsafe-math-optimizations. Creo que está activado por defecto, quizás puedas intentar configurarlo de forma explícita y ver si hace la diferencia. Del mismo modo, puede intentar desactivar explícitamente todas las optimizaciones de matemática máxima: -fno-finite-math-only, -fmath-errno, -ftrapping-math, -frounding-math y -fsignaling-nans (las últimas 2 opciones son no predeterminado!)

+0

¡Gracias por la idea! 'no-unsafe-math-optimizations' está establecido de manera predeterminada, pero intenté con lo que sugirió y lo configuré explícitamente, pero no marcó la diferencia. – Boinst

+0

He "aceptado" esta respuesta por el momento, creo que responde mi pregunta, aunque desafortunadamente para mí no resolvió mi problema. :( – Boinst

+0

Perdón por escuchar eso, espero que alguien más tenga una mejor idea. –

4

No creo que haya un equivalente exacto. Puede intentar -mfpmath=sse en lugar del -mfpmath=387 predeterminado para ver si eso ayuda.

+0

¡Probaré esta solución! – Boinst

+0

Eso no ayudó :(¡pero gracias por la idea! – Boinst

+0

Cuál debería usar '-mfpmath = sse' o' -ffloat-store' resuelve mi problema. – EmptyData

17

Desde el GCC manual:

-ffloat tienda No almacene las variables de punto flotante en registros, e inhiben otras opciones que podrían cambiar si un valor de punto flotante se toma de un registro o memoria.

Esta opción evita el exceso de precisión indeseable en máquinas como la 68000 donde los registros flotantes (del 68881) mantienen más precisión de la que se supone que tiene un doble. Del mismo modo para la arquitectura x86. Para la mayoría de los programas, el exceso de precisión solo sirve, pero algunos programas se basan en la definición precisa del punto flotante IEEE. Utilice -ffloat-store para tales programas, después de modificarlos para almacenar todos los cálculos intermedios pertinentes en variables.

Para ampliar un poco, la mayoría de estas discrepancias provienen de la utilización de los x86 registros de coma flotante de 80 bits para los cálculos (frente a los 64-bits utilizados para almacenar double valores).Si los resultados intermedios se guardan en los registros sin volver a escribir en la memoria, obtienes 16 bits de precisión adicional en tus cálculos, haciéndolos más precisos pero posiblemente divergentes de los resultados generados con la escritura/lectura de valores intermedios en la memoria (o de cálculos en arquitecturas que solo tienen registros FP de 64 bits).

Estos indicadores (tanto en GCC como en MSVC) generalmente fuerzan el truncamiento de cada resultado intermedio a 64 bits, lo que hace que los cálculos sean insensibles a los caprichos de generación y optimización de código y diferencias de plataforma. Esta coherencia generalmente viene con un costo de tiempo de ejecución menor además del costo en términos de precisión/precisión.

+0

Lo intentaré de inmediato – Boinst

+0

Esto no resultó ser el problema, pero gracias por su respuesta bien pensada. Su enlace fue muy útil – Boinst

+0

Lamento escucharlo. Tal vez tiene algo que ver con los modos de redondeo? Puede echar un vistazo al conjunto generado para un programa mínimo para el que obtiene resultados divergentes y ver si la FPU está configurada de forma diferente en MSVC frente a GCC. Luego puede intentar asignar esas configuraciones de FPU a diferentes banderas de compilación hasta que encuentre la bandera mágica. –

1

Esto definitivamente no está relacionado con las marcas de optimización, suponiendo que por "Depuración" quiere decir "con las optimizaciones desactivadas". Si g ++ da los mismos resultados en la depuración que en la versión, eso significa que no es un problema relacionado con la optimización. Las compilaciones de depuración siempre deben almacenar cada resultado intermedio en la memoria, garantizando así los mismos resultados que/fp: lo que hace exactamente para MSVC.

Esto probablemente significa que hay (a) un error de compilación en uno de los compiladores, o más probablemente (b) un error de la biblioteca matemática. Analizaría las funciones individuales en su cálculo y reduciría la discrepancia. Es probable que encuentre una solución alternativa en ese punto, y si encuentra un error, estoy seguro de que al equipo relevante le encantaría escucharlo.

+0

Gracias Drew, creo que tienes razón, y haré lo que sugieras – Boinst

0

-mpc32 o -mpc64?

Pero es posible que tenga que volver a compilar bibliotecas C y matemáticas con el interruptor para ver la diferencia ... Esto puede aplicarse a otras opciones sugeridas también.

Cuestiones relacionadas