Méritos relativos da computação de ponto fixo vs ponto flutuante?

9

Eu tenho um sistema de processamento de sinal digital que opera em uma máquina x86 rápida usando números de ponto flutuante de precisão dupla . Ocorreu-me que eu realmente não estou usando a enorme faixa dinâmica da representação de ponto flutuante - todas as quantidades cabem facilmente na faixa ± 32768.

Minha pergunta: é possível que a mudança para cálculos de ponto fixo forneça um benefício em precisão numérica (alta prioridade) ou tempo de computação (baixa prioridade)?

Obviamente, a resposta depende de quantos bits estão disponíveis para um cálculo de ponto fixo. Quantos bits de precisão os sistemas típicos de ponto fixo utilizam? É possível fazer cálculos de ponto fixo com eficiência, com, digamos, 64 bits ( parte inteira de 16 bits, parte fracionária de 48 bits ) em x86-64?

Eu sempre pensei que os cálculos de ponto fixo eram usados ​​apenas em situações onde a energia da CPU é limitada - faz sentido usar cálculos de ponto fixo quando a energia da CPU não é uma preocupação?

nibot
fonte
Você realmente precisa de mais do que os ~ 15 números significativos que um valor de ponto flutuante de precisão dupla fornece? Embora amplas generalizações sejam ruins, eu diria que, se você analisar o conjunto de todos os sistemas DSP de ponto fixo, é provável que os números inteiros de 16 bits sejam o formato mais comum.
Jason R

Respostas:

7

A precisão numérica dos números inteiros só será melhor que a precisão numérica dos flutuadores se a resolução inteira for melhor. Os duplos têm 52 bits fracionários; portanto, flutuadores de precisão dupla têm uma resolução pior que números inteiros em torno de , que é muito maior que 32768 ( 2 15 ). Portanto, não, a precisão numérica não será melhor se você usar números inteiros.252215

A segunda questão é a velocidade. A resposta é: depende do hardware. Se você estiver executando seu programa em um processador de sinal digital que possua múltiplos núcleos de multiplicação / acumulação de ponto fixo, então sim, será muito mais rápido no ponto fixo. Em um chip x86, por outro lado, provavelmente será mais lento no ponto fixo. Fiz exatamente o que você está falando uma vez e viu meus tempos de execução aumentarem.

Depois de fazer algumas pesquisas na internet, descobri que isso é comum. O motivo é que ele possui um processador de ponto flutuante dedicado que não faz nada quando você faz a transição para o ponto fixo, enquanto o hardware de ponto fixo é compartilhado com a ação regular de ponto fixo, como a aritmética de ponteiros.

Se você deseja acelerar o processamento, a maneira de fazer isso é mudar de flutuadores de precisão dupla para flutuadores de precisão única. Isso deve produzir um aumento significativo na velocidade. Obviamente, isso reduziria sua precisão numérica.

Jim Clay
fonte
Eu queria dizer o que essa resposta diz quando escrevi a minha. Este é melhor. Se não me engano, também li em algum lugar que em alguns computadores (64 bits, talvez?) O tipo de ponto flutuante do hardware nativo é duplo, portanto, o uso de flutuadores de precisão única (quatro bytes) pode ser mais lento. Isso é algo a ser levado em consideração, de qualquer maneira.
heltonbiker
Flutuadores de precisão única têm mantissae de 23 bits, os duplos têm 52 bits.
Paul R
Estou sugerindo uma fração de 16 bits inteiro + 48 bits como alternativa ao ponto flutuante de precisão dupla. Mencionei 32768 para indicar que meus valores se encaixam facilmente nesse intervalo. Dada a restrição a esses valores, acho que Q16.48 forneceria maior precisão numérica do que o ponto flutuante de precisão dupla.
Nibot 29/10/12
11
@nibot Okay. Os duplos teriam melhor precisão de -16 a +16, e os números inteiros fracionários teriam melhor precisão em outros lugares, até -32769 e +32768. É claro que eles não poderiam representar nada além disso. Eles também seriam mais lentos que duplos. Para mim, o alcance limitado e a velocidade lenta seriam disjuntores, mas YMMV.
Jim Clay
6

Os méritos do ponto fixo são principalmente em termos de energia (como quando você tem uma opção de hardware do processador ou o processador é bom em desligar unidades funcionais não utilizadas). Isso ocorre porque as unidades de ponto fixo são geralmente menores (menos transistores, fios mais curtos, menos capacitância a superar por MAC) para uma dada taxa de emissão de tecnologia e operação do que o ponto flutuante.

No entanto, uma grande quantidade de processadores contemporâneos comuns (servidor, PC e até móvel) possui FPUs cada vez mais rápidas (especialmente unidades FP de precisão única) do que multiplicadores inteiros, e a maior parte da energia do sistema não é o uso da FPU, portanto, o uso de fixos O point-point terá pouca ou nenhuma vantagem para a computação típica de DSP nesses produtos e provavelmente pode ser uma desvantagem em termos de desempenho puro. Usando a tecnologia atual, qualquer vantagem para o ponto fixo se acumulará principalmente em pequenos produtos incorporados, como dispositivos do tamanho de botões.

No entanto, considere também as pegadas de cache da memória e do processador. O uso inteligente de tipos de dados menores (short int e float) para ajustar completamente uma computação grande no cache de dados pode compensar qualquer vantagem pura da largura de banda da FPU.

hotpaw2
fonte
2
+1 pela menção da importância dos problemas de cache com relação ao desempenho. Nos modernos processadores x86, projetar seu algoritmo com o cache em mente pode ter um efeito enorme no desempenho.
Jason R
5

Prefira flutuações de precisão única a duplicadas - isso reduzirá pela metade a largura de banda da memória, a área de cache e os requisitos de armazenamento, além de tornar mais rápidas as operações matemáticas. Também abre a possibilidade de SIMD de 4 vias, se for necessária uma otimização adicional.

O ponto fixo só vale realmente a pena quando você não possui uma FPU - as CPUs x86 mais modernas têm duas FPUs; portanto, não há nada a ganhar com o uso do ponto fixo, e o desempenho pode ser significativamente pior com o ponto fixo. (Observe também que o ponto fixo requer instruções adicionais em comparação com o ponto flutuante para operações como multiplicação.)

Paul R
fonte
Estou interessado em aumentar a precisão numérica, não em reduzi-la.
Nibot 29/10/12
Como você vê o ponto fixo melhorando a precisão numérica em relação ao dobro, que tem 52 bits de precisão e uma enorme faixa dinâmica?
Paul R
Bem, eu poderia usar um formato de ponto fixo com mais de 52 bits.
Nibot 31/10/12
Como você aparentemente precisa de pelo menos 16 bits para a parte inteira da sua representação de ponto fixo, isso levará mais de 64 bits, então você provavelmente está procurando um formato para o qual sua CPU nem sequer tem instruções inteiras nativas. Nesse caso, você também pode usar apenas uma grande biblioteca inteira existente ou similar. A pergunta mais importante a ser respondida é: quanta precisão você realmente precisa ?
Paul R
3

Além das respostas muito boas fornecidas aqui, vale a pena acrescentar algumas coisas:

  • Existem situações em que, mesmo que você tenha requisitos muito básicos sobre a faixa dinâmica dos dados que processa, ainda precisará de uma precisão muito boa para algumas das operações executadas nele - por exemplo, você deseja aplicar um filtro IIR que requer coeficientes relativamente pequenos; e truncá-los causaria instabilidades. Assim que seu sistema receber feedback, há uma boa chance de que problemas de quantização / truncamento o atrapalhem ao usar o ponto fixo - você deve ter muito mais cuidado com coisas como topologia de filtro e esquemas de economia de truncamento / fração.
  • Diferentemente de muitas arquiteturas DSP / DSC, o x86 não possui operações inteiras saturadas (bem, existe no SSE, não no código escalar padrão). Isso significa que, em caso de transbordamento, coisas ruins podem acontecer - valorizam a mudança de sinais e o "acondicionamento". Você precisa ser extremamente cauteloso com estouros e faixa dinâmica ou testes de aspersão em faixas de operandosem todo o seu código. Isso pode prejudicar seriamente o desempenho. Em comparação, o ponto flutuante é mais resiliente a esses problemas, porque a grande faixa dinâmica oferece mais "espaço livre" e os estouros não levarão a falhas catastróficas. A maioria dos códigos de processamento de sinal de áudio executados em computadores de mesa usa o intervalo -1,0 .. 1,0, precisão simples ou dupla; portanto, isso fornece mais de centenas de dB de espaço livre. Escrevi código de processamento de sinal de áudio com as duas abordagens e, ao usar o ponto flutuante, existem apenas alguns lugares em que preciso explicitamente cortar / saturar o sinal - geralmente apenas no final da cadeia de processamento de sinal ou em locais onde o feedback ocorre.
pichenettes
fonte
1

Alguns pontos a considerar:

  • A maioria dos processadores modernos otimiza o processamento de números de ponto flutuante há muitos anos, e até as GPUs já estão sendo usadas com muito êxito;
  • Os cálculos de ponto fixo prejudicam seus dados e podem causar sérios problemas quando as operações aritméticas não são bem-condicionadas (é por isso que os números de ponto fixo foram substituídos pelos de ponto flutuante);
  • Mesmo se você usar shorts assinados para CONTINENTAR seus dados (os registradores de dados de lotes usam precisão de 16 bits), os CÁLCULOS devem ser feitos em ponto flutuante e depois convertidos em números inteiros; caso contrário, poderá haver artefatos como quantização e alias.

Como palavra final, acho que nossos dados do mundo real são preciosos e o processamento de números cegos do computador é um trabalho humilde e servil. O computador deve ser colocado para fazer o trabalho pesado para seus dados e para você, e não deve ser tratado como se fosse a verdadeira estrela do programa.

heltonbiker
fonte
Não pretendi sugerir que usaria shorts de 16 bits para conter minhas quantidades, mas algo como um formato de ponto fixo de 64 bits com uma parte inteira de 16 bits e uma parte fracionária de 48 bits. A motivação é que, se eu não estiver usando a maioria dos bits de expoente no formato de ponto flutuante, minha precisão numérica melhoraria se eu os usasse para fornecer dígitos significativos adicionais?
Nibot 29/10/12
215
Mais uma coisa: parece-me que o StackOverflow (em vez do DSP.SE, aqui) seria o local ideal para obter razões mais profundas sobre os prós e contras de um formato sobre o outro.
heltonbiker