Em todos os lugares que eu olhei, diz que double
é superior a float
quase todos os aspectos. float
ficou obsoleto double
em Java, então por que ainda é usado?
Eu programo muito com o Libgdx e eles o forçam a usar float
(deltaTime, etc.), mas me parece que double
é mais fácil trabalhar com isso em termos de armazenamento e memória.
Também li Quando você usa float e quando usa double , mas se float
é realmente bom apenas para números com muitos dígitos após o ponto decimal, por que não podemos simplesmente usar uma das muitas variações de double
?
Existe alguma razão para as pessoas insistirem em usar carros alegóricos, mesmo que isso não tenha mais vantagens? É muito trabalho mudar tudo?
java
memory
floating-point
numbers
Eames
fonte
fonte
byte
eshort
eint
quando hálong
?Respostas:
O LibGDX é um framework usado principalmente para o desenvolvimento de jogos.
No desenvolvimento de jogos, você geralmente precisa fazer um monte de trituração de números em tempo real e qualquer desempenho que possa obter. É por isso que os desenvolvedores de jogos geralmente usam float sempre que a precisão do float é boa o suficiente.
O tamanho dos registros da FPU na CPU não é a única coisa que você precisa considerar neste caso. De fato, a maior parte do processamento pesado de números no desenvolvimento de jogos é feita pela GPU, e as GPUs geralmente são otimizadas para carros alegóricos, não duplos .
E depois há também:
que são todos os recursos preciosos, dos quais você obtém o dobro quando usa o flutuador de 32 bits em vez do dobro de 64 bits.
fonte
Os carros alegóricos usam metade da memória dobra.
Eles podem ter menos precisão do que o dobro, mas muitos aplicativos não exigem precisão. Eles têm um alcance maior do que qualquer formato de ponto fixo de tamanho semelhante. Portanto, eles preenchem um nicho que precisa de amplos intervalos de números, mas não precisa de alta precisão, e onde o uso da memória é importante. Eu os usei para grandes sistemas de redes neurais no passado, por exemplo.
Além de Java, eles também são amplamente utilizados em gráficos 3D, porque muitas GPUs os utilizam como formato principal - fora dos dispositivos NVIDIA Tesla / AMD FirePro muito caros, o ponto flutuante de precisão dupla é muito lento nas GPUs.
fonte
Compatibilidade com versões anteriores
Esta é a razão número um para manter o comportamento em um idioma / biblioteca / ISA / etc já existente .
Considere o que aconteceria se eles retirassem carros alegóricos do Java. Libgdx (e milhares de outras bibliotecas e programas) não funcionariam. Será necessário muito esforço para atualizar tudo, possivelmente anos para muitos projetos (basta olhar para a transição de Python 2 para Python 3 de quebra de compatibilidade com versões anteriores). E nem tudo será atualizado, algumas coisas serão quebradas para sempre porque os mantenedores os abandonaram, talvez mais cedo do que teriam, porque seria necessário mais esforço do que eles desejam atualizar ou porque não é mais possível realizar o que seu software deveria façam.
atuação
As duplas de 64 bits ocupam o dobro da memória e são quase sempre mais lentas do que as flutuações de 32 bits (as exceções muito raras são quando a capacidade de flutuação de 32 bits deve ser usada tão raramente ou de maneira alguma, que nenhum esforço foi feito para otimizá-las A menos que você esteja desenvolvendo para hardware especializado, não poderá experimentar isso em um futuro próximo.)
Especialmente relevante para você, o Libgdx é uma biblioteca de jogos. Os jogos tendem a ser mais sensíveis ao desempenho do que a maioria dos softwares. E placas gráficas de jogos (ou seja, AMD Radeon e NVIDIA Geforce, não FirePro ou Quadro) tendem a ter um desempenho de ponto flutuante de 64 bits muito fraco. Cortesia de Anandtech, veja como o desempenho de precisão dupla se compara ao desempenho de precisão única em algumas das principais placas de jogos da AMD e da NVIDIA disponíveis (no início de 2016)
Observe que as séries R9 Fury e GTX 900 são mais recentes que as séries R9 200 e GTX 700; portanto, o desempenho relativo do ponto flutuante de 64 bits está diminuindo. Volte o suficiente e você encontrará a GTX 580, que tinha uma proporção de 1/8 como a série R9 200.
1/32 do desempenho é uma penalidade muito grande a pagar se você tiver uma restrição de tempo apertada e não ganhar muito usando o dobro maior.
fonte
Operações atômicas
Além do que outros já disseram, uma desvantagem específica de Java de
double
(elong
) é que não é garantido que as atribuições para tipos primitivos de 64 bits sejam atômicas . Na especificação da linguagem Java, Java SE 8 Edition , página 660 (ênfase adicionada):Que nojo.
Para evitar isso, você deve declarar a variável de 64 bits com a
volatile
palavra - chave ou usar outra forma de sincronização nas atribuições.fonte
Parece que outras respostas perderam um ponto importante: As arquiteturas do SIMD podem processar menos / mais dados, dependendo se operam
double
ou sefloat
estruturam (por exemplo, oito valores flutuantes por vez ou quatro valores duplos por vez).Resumo das Considerações de Desempenho
float
pode ser mais rápido em determinadas CPUs (por exemplo, determinados dispositivos móveis).float
usa menos memória, portanto, em grandes conjuntos de dados, pode reduzir substancialmente a memória total necessária (disco rígido / RAM) e a largura de banda consumida.float
pode fazer com que uma CPU consuma menos energia (não consigo encontrar uma referência, mas se não for possível, pelo menos parece plausível) para cálculos de precisão única em comparação com cálculos de precisão dupla.float
consome menos largura de banda e, em alguns aplicativos, o que importa.float
usa até metade da memória cache em comparação com o dobro.Resumo das Considerações de Precisão
float
é suficientedouble
tem muito mais precisão de qualquer maneiraConsiderações de compatibilidade
double
(isso ocorre porque os fabricantes de GPU tentam aumentar o número de núcleos gráficos e assim, eles tentam economizar o máximo de circuitos possível em cada núcleo, otimizando parafloat
criar GPUs com mais núcleos)double
como formato interno (para operações de renderização em 3D)Dicas gerais
double
variáveis temporárias na pilha fornece precisão extra de graça (precisão extra sem penalização de desempenho).float
, mas podem ser valores limitados se você estiver usandodouble
)float
ou apenasdouble
ajuda bastante o compilador a SIMD-ify as instruções.Veja os comentários abaixo de PeterCordes para mais informações.
fonte
double
temporários só é gratuito no x86 com o x87 FPU, não no SSE2. Auto-vetorizar um loop comdouble
temporários significa descompactarfloat
paradouble
, o que requer uma instrução extra, e você processa metade do número de elementos por vetor. Sem a vetorização automática, a conversão geralmente pode ocorrer em tempo real durante uma carga ou armazenamento, mas significa instruções extras quando você está misturando carros alegóricos e duplos nas expressões.Além dos outros motivos mencionados:
Se você possui dados de medição, sejam pressões, fluxos, correntes, tensões ou qualquer outra coisa, isso geralmente é feito com hardware com um ADC.
Um ADC normalmente possui 10 ou 12 bits, enquanto os de 14 ou 16 bits são mais raros. Mas vamos ficar com o de 16 bits - se medir em escala completa, você terá uma precisão de 1/65535. Isso significa que uma alteração de 65534/65535 para 65535/65535 é apenas esta etapa - 1/65535. Isso é aproximadamente 1.5E-05. A precisão de um flutuador é de cerca de 1E-07, muito melhor. Isso significa que você não perde nada usando
float
para armazenar esses dados.Se você fizer cálculos excessivos com flutuadores, terá um desempenho levemente pior do que
doubles
em termos de precisão, mas muitas vezes não precisará dessa precisão, pois muitas vezes não se importa se apenas mediu uma tensão de 2 V ou 2.00002 V. , se você converter essa tensão em pressão, não se importará se possui 3 bar ou 3,00003 bar.fonte