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?
@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.
"É 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).
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.
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.
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.
Respostas:
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.
fonte
Existem três maneiras de fazer aritmética de ponto flutuante:
fonte
A rigor, todas essas respostas parecem erradas para mim.
O wiki do Debian VFP tem informações sobre as três opções para
-mfloat-abi
,soft
- é puro softwaresoftfp
- 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=softfp
forma 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=none
para 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.
fonte
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.
fonte
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.
fonte