Como um ponto flutuante de 80 bits pode ser usado por um sistema de 32 bits? [duplicado]

13

Como um sistema de 32 bits não pode gerenciar um número 2 ^ 33 (porque o óbvio limite de 32 bits), como gerenciar um Ponto flutuante de 80 bits número?

Deve exigir "80 bits" ...

    
por markzzz 30.07.2014 / 17:19

5 respostas

35

Um dos significados de uma CPU de 32 bits é que seus registradores têm 32 bits de largura. Isso não significa que não se possa lidar com números de 64 bits, apenas que ele tem que lidar com a metade de 32 bits mais baixa primeiro, depois com a metade de 32 bits de segundo superior. (É por isso que as CPUs têm um carry flag .) É mais lento do que se a CPU pudesse apenas carregar os valores em um bit maior de 64 bits. registrar, mas ainda é possível.

Assim, o "bitness" de um sistema não limita necessariamente o tamanho dos números com os quais um programa pode lidar, porque você sempre pode dividir as operações que não se encaixam nos registradores da CPU em múltiplas operações. Por isso, torna as operações mais lentas, consome mais memória (se você tiver que usar a memória como um "bloco de notas") e mais difícil de programar, mas as operações ainda são possíveis.

No entanto, nada disso importa, por exemplo, com processadores Intel de 32 bits e ponto flutuante, já que a parte de ponto flutuante da CPU tem seus próprios registradores e eles têm 80 bits de largura. (No início da história do x86, o recurso de ponto flutuante era um chip separado, foi integrado no processador começando com 80486DX.)

@ A resposta da Breakthrough me inspirou a acrescentar isso.

Valores de ponto flutuante, na medida em que são armazenados nos registradores FPU, funcionam muito diferentes dos valores inteiros binários.

Os 80 bits de um valor de ponto flutuante são divididos entre uma mantissa e um expoente (há também a "base" em números de ponto flutuante que é sempre 2). A mantissa contém os dígitos significativos e o expoente determina o tamanho desses dígitos significativos. Portanto, não há "estouro" em outro registrador, se o seu número ficar muito grande para caber na mantissa, seu expoente aumenta e você perde a precisão - ou seja, quando você o converte em um inteiro, você perderá casas decimais à direita - É por isso que é chamado ponto flutuante.

Se o seu expoente é muito grande, então você tem um estouro de ponto flutuante, mas você não pode facilmente estendê-lo para outro registro, já que o expoente e a mantissa estão amarrados juntos.

Eu poderia ser impreciso e errado sobre isso, mas eu acredito que é a essência disso. (Este artigo da Wikipedia ilustra o texto acima de forma mais sucinta.)

Tudo bem que isso funcione de maneira totalmente diferente, já que toda a parte de "ponto flutuante" da CPU está em seu próprio mundo - você usa instruções especiais da CPU para acessá-la e coisas do tipo. Além disso, em direção ao ponto da questão, porque é separado, a bitur da FPU não é strongmente acoplada com bitness da CPU nativa.

    
por 30.07.2014 / 17:24
13

32 bits, 64 bits e 128 bits, todos se referem ao tamanho da palavra o processador, que pode ser considerado como o "tipo de dados fundamentais". Freqüentemente, esse é o número de bits transferidos para / da RAM do sistema e a largura dos ponteiros (embora nada impeça você de usar o software para acessar mais RAM do que um único ponteiro pode acessar).

Supondo que uma velocidade de clock constante (assim como todo o restante da arquitetura é constante), e assumindo que as leituras / gravações de memória tenham a mesma velocidade (assumimos 1 ciclo de clock aqui, mas isso está longe de ser real) , você pode adicionar dois números de 64 bits em um único ciclo de clock em uma máquina de 64 bits (três, se contar a busca dos números da RAM):

ADDA [NUM1], [NUM2]
STAA [RESULT]

Também podemos fazer o mesmo cálculo em uma máquina de 32 bits. No entanto, em uma máquina de 32 bits, precisamos fazer isso em software, já que os 32 bits inferiores devem ser adicionado primeiro, compensar o estouro e, em seguida, adicionar os 64 bits superiores:

     ADDA [NUM1_LOWER], [NUM2_LOWER]
     STAA [RESULT_LOWER]
     CLRA          ; I'm assuming the condition flags are not modified by this.
     BRNO CMPS     ; Branch to CMPS if there was no overflow.
     ADDA #1       ; If there was overflow, compensate the value of A.
CMPS ADDA [NUM1_UPPER], [NUM2_UPPER]
     STAA [RESULT_UPPER]

Percorrendo a sintaxe de montagem confeccionada, você pode ver facilmente como operações de maior precisão podem levar um tempo exponencialmente maior em uma máquina com comprimento de palavra menor. Esta é a verdadeira chave para processadores de 64 bits e 128 bits: eles nos permitem lidar com números maiores de bits em uma única operação. Algumas máquinas incluem instruções para adicionar outras quantidades com transporte (por exemplo, ADC on x86), mas o exemplo acima tem valores de precisão arbitrários em mente.

Agora, para estender isso para a questão, é simples ver como podemos adicionar números maiores que os registros que temos disponíveis - apenas dividimos o problema em partes do tamanho dos registradores e trabalhamos a partir daí. Embora como mencionado por @MatteoItalia , a pilha x87 FPU tem suporte nativo para quantidades de 80 bits, em sistemas que não possuem este suporte (ou processadores sem uma unidade de ponto flutuante totalmente!), os cálculos / operações equivalentes devem ser executados no software .

Portanto, para um número de 80 bits, depois de adicionar cada segmento de 32 bits, também é necessário verificar se há excesso de vazão no bit 81-st e, opcionalmente, zerar os bits de ordem superior. Essas verificações / zeros são executadas automaticamente para determinadas instruções x86 e x86-64, em que os tamanhos dos operandos de origem e destino são especificados (embora sejam especificados apenas em potências de 2 a partir de 1 byte).

É claro que, com números de ponto flutuante, não se pode simplesmente executar a adição binária, pois a mantissa e os dígitos significativos são empacotados juntos na forma offset. Na ALU em um processador x86, há um circuito de hardware para executar isso em flutuadores IEEE de 32 e 64 bits; no entanto , mesmo na ausência de uma unidade de ponto flutuante (FPU), os mesmos cálculos podem ser executados em software (por exemplo, através do uso do Biblioteca Científica GNU , que usa um FPU quando compilado em arquiteturas, recorrendo a algoritmos de software se não houver hardware de ponto flutuante disponível [por exemplo, para microcontroladores incorporados sem FPUs]).

Dada memória suficiente, também é possível realizar cálculos em números de precisão arbitrária (ou "infinita" - dentro de limites realísticos), usando mais memória à medida que mais precisão é necessária. Uma implementação disso existe na biblioteca GNU Multiple Precision , permitindo uma precisão ilimitada (até que sua RAM esteja cheia, é claro) no inteiro, racional e operações de ponto flutuante.

    
por 30.07.2014 / 17:52
5

A arquitetura de memória do sistema pode permitir que você apenas mova 32 bits de uma só vez - mas isso não impede o uso de números maiores.

Pense em multiplicação. Você pode conhecer suas tabelas de multiplicação em até 10x10, mas você provavelmente não terá problemas em executar 123x321 em um pedaço de papel: você o divide em pequenos problemas, multiplicando dígitos individuais e cuidando do transporte etc.

Os processadores podem fazer a mesma coisa. Nos "velhos tempos" você tinha processadores de 8 bits que faziam contas de ponto flutuante. Mas eles foram slooooooow.

    
por 30.07.2014 / 17:23
3

"32 bits" é realmente uma maneira de categorizar processadores, não uma regra definitiva. um processador de "32 bits" normalmente possui registros de propósito geral de 32 bits para trabalhar.

No entanto, não há nenhum requisito definido em pedra para que tudo no processador seja feito em 32 bits. Por exemplo, não era inédito para um computador de "32 bits" ter um barramento de endereços de 28 bits, porque era mais barato fazer o hardware. Computadores de 64 bits geralmente possuem apenas um barramento de memória de 40 ou 48 bits pelo mesmo motivo.

A aritmética de ponto flutuante é outro local onde os tamanhos variam. Muitos processadores de 32 bits suportavam números de ponto flutuante de 64 bits. Eles fizeram isso armazenando os valores de ponto flutuante em registros especiais que eram mais largos do que os registradores de propósito geral. Para armazenar um desses números grandes de ponto flutuante nos registros especiais, primeiro seria dividido o número entre dois registradores de uso geral e, em seguida, emitimos uma instrução para combiná-los em um ponto flutuante nos registros especiais. Uma vez nesses registradores de ponto flutuante, os valores seriam manipulados como floats de 64 bits, em vez de um par de metades de 32 bits.

A aritmética de 80 bits mencionada é um caso especial disso. Se você trabalhou com números de ponto flutuante, está familiarizado com a imprecisão que surge dos problemas de arredondamento de ponto flutuante. Uma solução para o roundoff é ter mais bits de precisão, mas você precisa armazenar números maiores e forçar os desenvolvedores a usar valores de ponto flutuante incomumente grandes na memória.

A solução da Intel é que os registradores de ponto flutuante são todos de 80 bits, mas as instruções para mover valores de / para esses registros trabalham principalmente com números de 64 bits. Desde que você opere totalmente dentro da pilha de ponto flutuante x87 da Intel, todas as suas operações são feitas com 80 bits de precisão. Se seu código precisar extrair um desses valores dos registradores de ponto flutuante e armazená-lo em algum lugar, truncá-lo-á para 64 bits.

Moral da história: categorizações como "32 bits" são sempre mais perigosas quando você se aprofunda nas coisas!

    
por 31.07.2014 / 00:12
2

Uma CPU de "32 bits" é aquela em que a maioria dos registradores de dados são registradores de 32 bits, e a maioria das instruções opera com dados nesses registros de 32 bits. Uma CPU de 32 bits provavelmente também transferirá dados de e para a memória de 32 bits por vez. A maioria dos registros sendo de 32 bits não significa que todos os registros sejam de 32 bits. A resposta curta é que uma CPU de 32 bits pode ter alguns recursos que usam outros contadores de bits, como registradores de ponto flutuante de 80 bits e instruções correspondentes.

Como o @spudone disse em um comentário sobre a resposta do @ ultrasawblade, o primeiro processador x86 a ter operações de ponto flutuante integrado foi o Intel i486 (especificamente o 80486DX mas não o 80486SX), que, de acordo com Página 15-1 do Manual de Referência de Programadores de Microprocessador i486 , inclui em seus registros numéricos" Oito endereços individuais 80- registros numéricos de bit ". O i486 tem um barramento de memória de 32 bits, portanto, a transferência de um valor de 80 bits levaria três operações de memória.

O predecessor da geração 486, o i386, não tinha nenhuma operação integrada de ponto flutuante. Em vez disso, ele tinha suporte para o uso de um "coprocessador" de ponto flutuante externo, o 80387. Esse coprocessador tinha quase a mesma funcionalidade que foi integrada ao i486, como você pode ver em Página 2-1 do 80387 Programmer's Reference Manual .

O formato de ponto flutuante de 80 bits parece ter se originado com o 8087, o coprocessador matemático para o 8086 e o 8088. O 8086 e o 8088 eram CPUs de 16 bits (com barramentos de memória de 16 e 8 bits) e ainda eram capazes de usar o formato de ponto flutuante de 80 bits, aproveitando os registros de 80 bits no coprocessador.

    
por 31.07.2014 / 03:59

Tags