Qual é a diferença entre números de ponto flutuante hard e soft?


98

Quando eu compilo o código C com minha cadeia de ferramentas cruzada, o vinculador imprime páginas de avisos dizendo que meu executável usa floats rígidos, mas minha libc usa floats suaves. Qual é a diferença?


Se for arquitetura ARM, coloque-o nas tags :-)
Nils Pipenbrinck

3
@Nils Pipenbrinck: Os chips MIPS também têm esse problema
Javier

Respostas:


100

Os flutuadores rígidos usam uma unidade de ponto flutuante no chip. Os flutuadores suaves emulam um no software. A diferença é a velocidade. É estranho ver os dois usados ​​na mesma arquitetura de destino, já que o chip tem ou não uma FPU. Você pode habilitar o ponto flutuante suave no GCC com -msoft-float. Você pode querer recompilar seu libc para usar ponto flutuante de hardware se você usá-lo.


3
"É estranho ver ambos usados ​​na mesma arquitetura de destino" Isso pode fazer sentido para uma biblioteca ser independente da máquina e bit-exata (flutuação suave) em partes críticas de precisão e rápida (flutuação rígida) em partes onde pequenos desvios não não importa.
PhilLab

Acontece no ARM de 32 bits.
Aaron Franke

31

Existem três maneiras de fazer aritmética de ponto flutuante:

  • Use as instruções de flutuação se sua CPU tiver uma FPU. (velozes)
  • Faça com que seu compilador traduza a aritmética de ponto flutuante em aritmética de inteiro. (lento)
  • Use as instruções de flutuação e uma CPU sem FPU. Sua CPU irá gerar uma exceção (instrução reservada, instrução não implementada ou similar), e se o kernel do sistema operacional incluir um emulador de ponto flutuante, ele emulará essas instruções (mais lentas).

23

A rigor, todas essas respostas parecem erradas para mim.

Quando eu compilo o código C com minha cadeia de ferramentas cruzada, o vinculador imprime páginas de avisos dizendo que meu executável usa floats rígidos, mas minha libc usa floats suaves. Qual é a diferença?

O wiki do Debian VFP tem informações sobre as três opções para -mfloat-abi,

  • soft - é puro software
  • softfp- suporta um FPU de hardware, mas o ABI é compatível com software.
  • hard- a ABI usa registros float ou VFP .

O erro do vinculador (carregador) é porque você tem uma biblioteca compartilhada que irá passar valores de ponto flutuante em registradores inteiros. Você ainda pode compilar seu código com um -mfpu=vfp, etc, mas deve usar de -mfloat-abi=softfpforma que, se a libc precisar de um float, ele seja passado de uma maneira que a biblioteca entenda.

O kernel do Linux pode suportar a emulação das instruções VFP. Obviamente, é melhor compilar -mfpu=nonepara este caso e fazer com que a compilação gere o código diretamente em vez de depender de qualquer emulação do kernel do Linux. No entanto, não acredito que o erro do OP esteja realmente relacionado a esse problema. É separado e também deve ser tratado junto com o -mfloat-abi.

A biblioteca compartilhada Armv5 com CPU ArmV7 é o oposto desta; a libc era flutuante, mas o aplicativo era apenas suave . Ele possui algumas maneiras de contornar o problema, mas recompilar com as opções corretas é sempre a mais fácil.

Outro problema é que o kernel do Linux deve suportar tarefas VFP (ou qualquer ponto flutuante ARM presente) para salvar / restaurar os registros em uma troca de contexto.


1
As versões modernas do GCC (~ 4.8 +) suportam 'multi-lib', que possui bibliotecas de flutuação rígida e flutuação suave. As versões anteriores exigiam que você tivesse um compilador construído com uma versão específica. Ocasionalmente, o caminho para a biblioteca correta é necessário ao vincular a uma distribuição gcc 'multi-lib', pois há várias versões das bibliotecas (exigindo mais tempo para construir o compilador). Os nomes de diretório podem ser 'hf', 'hardf', 'libhf' ou 'hard-float', mas geralmente estão no diretório 'soft' regular ou em um local próximo.
ruído natural de

Esta é a resposta certa. A conversão de chamada para floats precisa corresponder entre seu código e libc. Ele ainda pode funcionar com uma incompatibilidade, se você nunca chamar nenhuma função libc de ponto flutuante.
Tor Klingberg

13

Parece que seu libc foi construído para operações de ponto flutuante de software enquanto seu exe foi compilado assumindo suporte de hardware para ponto flutuante. No curto prazo, você pode forçar flutuações suaves como um sinalizador do compilador. (se você estiver usando gcc, acho que é -msoft-float)

A longo prazo, se o processador do seu alvo tiver suporte de hardware para operações de ponto flutuante, você geralmente desejará construir ou encontrar uma cadeia de ferramentas cruzada com flutuação de hardware habilitada para velocidade. Algumas famílias de processadores têm variantes de modelo, algumas com e outras sem suporte de hardware. Então, por exemplo, apenas dizer que seu processador é um ARM é insuficiente para saber se você tem suporte para ponto flutuante de hardware.


8

O cálculo pode ser feito por hardware de ponto flutuante ou em software baseado em aritmética inteira.

Fazer isso no hardware é muito mais rápido, mas muitos microcontroladores não possuem hardware de ponto flutuante. Nesse caso, você pode evitar o uso de ponto flutuante (geralmente a melhor opção) ou contar com uma implementação em software, que fará parte da biblioteca C.

Em algumas famílias de controladores, por exemplo ARM, o hardware de ponto flutuante está presente em alguns modelos da família, mas não em outros, portanto, o gcc para essas famílias oferece suporte a ambos. Seu problema parece ser que você confundiu as duas opções.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.