2010-07-23 13 views
81

Cuando compilo el código C con mi toolchain cruzado, el enlazador imprime páginas de advertencias que dicen que mi ejecutable usa flotantes duros, pero mi libc usa flotación suave. ¿Cual es la diferencia?¿Cuál es la diferencia entre números flotantes duros y blandos?

+0

Si se trata de arquitectura ARM, por favor ponga eso en las etiquetas :-) –

+3

@Nils Pipenbrinck: Los chips MIPS también tienen este problema – Javier

Respuesta

81

Los flotadores duros usan una unidad de punto flotante en el chip. Las carrozas suaves emulan una en el software. La diferencia es la velocidad. Es extraño ver ambos utilizados en la misma arquitectura de destino, ya que el chip tiene una FPU o no. Puede habilitar el punto flotante suave en GCC con -msoft-float. Es posible que desee recompilar su libc para usar el punto flotante de hardware si lo usa.

+0

"Es extraño ver ambos utilizados en la misma arquitectura de destino" Esto puede tener sentido para una biblioteca sean independientes de la máquina y bit-exactos (float suave) en partes de precisión crítica y rápidas (float duro) en partes donde las pequeñas desviaciones no importan. – PhilLab

10

Parece que su libc fue creada para operaciones de coma flotante de software mientras que su exe se compiló asumiendo el soporte de hardware para coma flotante. En el corto plazo, podría forzar carrozas blandas como indicador del compilador. (Si está utilizando gcc, creo que es -flojo flotante)

A más largo plazo, si el procesador de su destino tiene soporte de hardware para operaciones de coma flotante, generalmente querrá construir o encontrar una cadena de herramientas cruzada con hardware flotante habilitado para velocidad. Algunas familias de procesadores tienen algunas variantes de modelo y algunas sin soporte de hardware. Entonces, por ejemplo, decir que su procesador es un ARM es insuficiente para saber si tiene soporte de punto flotante de hardware.

28

Hay tres maneras de hacer la aritmética de punto flotante:

  • instrucciones Uso de flotador si su CPU tiene una FPU. (rápido)
  • Haga que su compilador traduzca la aritmética de punto flotante a la aritmética de enteros. (lento)
  • Utilice las instrucciones de flotación y una CPU sin FPU. Su CPU generará una excepción (Instrucción reservada, Instrucción no implementada o similar), y si su kernel OS incluye un emulador de punto flotante, emulará esas instrucciones (la más lenta).
6

El cálculo puede realizarse mediante hardware de coma flotante o en software basado en aritmética de enteros.

Hacerlo en hardware es mucho más rápido, pero muchos microcontroladores no tienen hardware de coma flotante. En ese caso, puede evitar el uso de punto flotante (generalmente la mejor opción) o confiar en una implementación en el software, que será parte de la biblioteca C.

En algunas familias de controladores, por ejemplo ARM, el hardware de coma flotante está presente en algunos modelos de la familia pero no en otros, por lo que gcc para estas familias admite ambos. Tu problema parece ser que confundiste las dos opciones.

11

Estrictamente hablando, todas estas respuestas me parecen incorrectas.

Cuando compilo el código C con mi toolchain cruzado, el enlazador imprime páginas de advertencias que dicen que mi ejecutable usa discos duros, pero mi libc usa flotación suave. ¿Cual es la diferencia?

El Debian VFP wiki tiene información sobre las tres opciones para -mfloat-abi,

  • soft - se trata de software puro
  • softfp - esto es compatible con una FPU hardware, pero el ABI es suave compatibles.
  • hard - el ABI usa float o VFP registros.

El error del enlazador (cargador) se debe a que tiene una biblioteca compartida que pasará los valores de punto flotante en los registros enteros. Todavía puede compilar su código con un -mfpu=vfp, etc. pero debe usar -mfloat-abi=softfp para que si el libc necesita un flotador, se pase de una manera que la biblioteca entienda.

El kernel de Linux puede admitir la emulación de las instrucciones de VFP. Obviamente, es mejor compilar con -mfpu=none para este caso y hacer que el compilador genere código directamente en lugar de confiar en cualquier emulación de kernel de Linux. Sin embargo, no creo que el error del PO esté realmente relacionado con este problema. Está separado y también debe tratarse junto con el -mfloat-abi.

Armv5 shared library with ArmV7 CPU es un opuesto a este; el libc era hard float pero la aplicación era solo soft. Tiene algunas formas de evitar el problema, pero recompilar con las opciones correctas es siempre lo más fácil.

Otro problema es que el kernel de Linux debe admitir tareas de VFP (o cualquier punto flotante ARM presente) para guardar/restaurar los registros en un cambio de contexto.

+0

Las versiones modernas de GCC (~ 4.8 +) son compatibles con 'multi-lib', que tienen librerías hard float y soft float. Las versiones anteriores requerían que tuvieras un compilador construido con una versión específica. Ocasionalmente, se necesita la ruta a la biblioteca correcta cuando se vincula con una distribución gcc 'multi-lib', ya que hay varias versiones de las bibliotecas (lo que requiere un tiempo más prolongado para compilar el compilador). Los nombres de directorio pueden ser 'hf', 'hardf', 'libhf' o 'hard-float', pero generalmente están en el directorio 'soft' normal o en una ubicación cercana. –

+0

Esta es la respuesta correcta. La conversión de llamadas para flotantes debe coincidir entre su código y libc. Todavía podría funcionar con una discrepancia, si nunca llama a ninguna función libc de punto flotante. –

Cuestiones relacionadas