¿Cuál es la diferencia entre números de punto flotante duros y blandos?

98

Cuando compilo código C con mi cadena de herramientas cruzada, el enlazador imprime páginas de advertencias que dicen que mi ejecutable usa flotantes duros pero mi libc usa flotantes suaves. ¿Cual es la diferencia?

Evan Kroske
fuente
Si se trata de arquitectura ARM, póngalo en las etiquetas :-)
Nils Pipenbrinck
3
@Nils Pipenbrinck: los chips MIPS también tienen este problema
Javier

Respuestas:

100

Los flotadores duros utilizan una unidad de punto flotante en chip. Los flotadores suaves emulan uno en el software. La diferencia es la velocidad. Es extraño ver que ambos se usen 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.

nmichaels
fuente
3
"Es extraño ver que ambos se usan en la misma arquitectura de destino". Esto puede tener sentido que una biblioteca sea independiente de la máquina y con precisión de bits (flotación suave) en partes de precisión crítica y rápida (flotación dura) en partes donde no se producen pequeñas desviaciones no importa.
PhilLab
Ocurre en ARM de 32 bits.
Aaron Franke
31

Hay tres formas de hacer aritmética de punto flotante:

  • Use instrucciones flotantes si su CPU tiene una FPU. (rápido)
  • Haga que su compilador traduzca aritmética de punto flotante a aritmética de enteros. (lento)
  • Utilice instrucciones flotantes y una CPU sin FPU. Su CPU generará una excepción (instrucción reservada, instrucción no implementada o similar), y si el kernel de su sistema operativo incluye un emulador de punto flotante, emulará esas instrucciones (la más lenta).
ninjalj
fuente
23

Estrictamente hablando, todas estas respuestas me parecen incorrectas.

Cuando compilo código C con mi cadena de herramientas cruzada, el enlazador imprime páginas de advertencias que dicen que mi ejecutable usa flotantes duros pero mi libc usa flotantes suaves. ¿Cual es la diferencia?

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

  • soft - esto es puro software
  • softfp- esto admite una FPU de hardware, pero la ABI es compatible con software.
  • hard- el ABI utiliza registros flotantes o VFP .

El error del vinculador (cargador) se debe a que tiene una biblioteca compartida que pasará valores de punto flotante en registros enteros. Aún puede compilar su código con a -mfpu=vfp, etc., pero debe usarlo -mfloat-abi=softfppara que si la libc necesita un flotante, 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=nonepara este caso y hacer que la compilación genere código directamente en lugar de depender de cualquier emulación del kernel de Linux. Sin embargo, no creo que el error del OP esté realmente relacionado con este problema. Es independiente y también debe tratarse junto con -mfloat-abi.

La biblioteca compartida Armv5 con CPU ArmV7 es opuesta a esta; el libc era hard float pero la aplicación solo era soft . Tiene algunas formas de solucionar el problema, pero volver a compilar con las opciones correctas siempre es lo más fácil.

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

ruido ingenuo
fuente
1
Las versiones modernas de GCC (~ 4.8 +) admiten 'multi-lib', que tienen bibliotecas 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 (que requieren más tiempo para compilar el compilador). Los nombres de los directorios pueden ser 'hf', 'hardf', 'libhf' o 'hard-float' pero normalmente se encuentran en el directorio normal 'soft' o en una ubicación cercana.
ruido sin arte
Esta es la respuesta correcta. La conversión de llamadas para flotantes debe coincidir entre su código y libc. Es posible que aún funcione con una falta de coincidencia, si nunca nunca llama a ninguna función libc de punto flotante.
Tor Klingberg
13

Parece que su libc se creó para operaciones de punto flotante de software, mientras que su exe se compiló asumiendo que el hardware es compatible con punto flotante. A corto plazo, podría forzar flotadores suaves como una bandera del compilador. (si está usando gcc, creo que es -msoft-float)

A largo plazo, si el procesador de su objetivo tiene soporte de hardware para operaciones de punto flotante, generalmente querrá construir o encontrar una cadena de herramientas cruzada con la flotación de hardware habilitada para la velocidad. Algunas familias de procesadores tienen variantes de modelos, algunas con y otras sin soporte de hardware. Entonces, por ejemplo, simplemente decir que su procesador es un ARM es insuficiente para saber si tiene soporte de punto flotante de hardware.

Digikata
fuente
8

El cálculo puede realizarse mediante hardware de punto 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 punto flotante. En ese caso, puede evitar el uso de punto flotante (generalmente la mejor opción) o confiar en una implementación en software, que será parte de la biblioteca C.

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

estrella azul
fuente