Por que a divisão é muito mais complexa do que outras operações aritméticas?

39

Recentemente, encontrei um caso em que precisava de uma operação de divisão inteira em um chip que não possuía um (ARM Cortex-A8). Enquanto tentava pesquisar por que isso deveria ser, descobri que na divisão geral são necessários muito mais ciclos do que adição, subtração ou multiplicação em praticamente qualquer arquitetura inteira (ou ponto fixo). Por que esse é o caso? Não é representável com uma lógica AND-OR de duas camadas, como todo o resto?

Phonon
fonte

Respostas:

34

Divisão é um algoritmo iterativo em que o resultado do quociente deve ser deslocado para o restante usando uma medida euclidiana, veja 2 ; enquanto que a multiplicação pode ser reduzida a uma série (fixa) de truques de manipulação de bits.

aterrel
fonte
2
Antes, a multiplicação e a divisão eram operações lentas. Atualmente, a multiplicação é um pouco mais rápida (mas um pouco mais lenta que a adição / subtração), mas a divisão ainda é mais lenta que as outras. Eu acredito que Newton-Raphson ainda é usado internamente pela maioria para retribuir um número.
JM
12
(Fora do tópico: "Operações inversas geralmente são difíceis. Basta olhar para integração versus diferenciação." - depende se o que você está fazendo é simbólico ou numérico. A diferenciação é simbolicamente fácil, mas numericamente difícil; a integração é simbolicamente difícil, mas numericamente fácil).
JM
1
Ok, vou entender dizendo que a cubatura é uma lata de vermes diferente; mas pelo menos no caso unidimensional, a quadratura é mais fácil que a diferenciação.
JM
1
De qualquer forma, inversos sempre vêm em pares. Por que você chamaria uma de "operação" e a outra de "inversa"?
David Ketcheson
2
Nem a iteração nem a inversa tornam mais difícil. A dureza de divisão vem do fato de que é necessário mudar o resultado do quociente para o restante usando uma medida euclidiana. Veja o teorema do algoritmo de divisão .
20

Embora todas as CPUs atuais pareçam usar uma abordagem iterativa, como o aterrel sugere , houve algum trabalho realizado em abordagens não iterativas. Divisão de ponto flutuante de precisão variável e raiz quadrada fala sobre uma implementação não iterativa de divisão de ponto flutuante e raiz quadrada em um FPGA , usando tabelas de pesquisa e expansão da série taylor.

Suspeito que as mesmas técnicas possam tornar essas operações reduzidas a um único ciclo (taxa de transferência, se não latência), mas é provável que você precise de grandes tabelas de pesquisa e, portanto, áreas imensamente grandes de imóveis de silício para fazer isso .

Por que não seria viável?

Ao projetar CPUs, há muitas vantagens e desvantagens. Funcionalidade, complexidade (número de transistores), velocidade e consumo de energia estão inter-relacionados e as decisões tomadas durante o projeto podem causar um enorme impacto no desempenho.

Um processador moderno provavelmente poderia ter uma unidade principal de ponto flutuante que dedique transistores suficientes no silício para executar uma divisão de ponto flutuante em um único ciclo , mas seria improvável que seja um uso eficiente desses transistores.

O ponto flutuante multiplicado fez essa transição de iterativo para não iterativo há uma década. Atualmente, a multiplicação de ciclo único e a acumulação de multiplicação são comuns, mesmo em processadores móveis.

Antes de se tornar um uso eficiente do orçamento do transistor, a multiplicação, como a divisão, era frequentemente realizada por um método iterativo. Naquela época, os processadores DSP dedicados podiam dedicar a maior parte de seu silício a uma única unidade rápida de multiplicação múltipla (MAC) . Uma CPU Core2duo possui uma latência de multiplicação de ponto flutuante de 3 (o valor sai do ciclo do pipeline 3 após a entrada), mas pode ter 3 multiplicações em voo ao mesmo tempo, resultando em uma taxa de transferência de ciclo único, enquanto a unidade SSE2 pode bombeie múltiplas multiplicações FP em um único ciclo.

Em vez de dedicar grandes áreas de silício a uma unidade de divisão de ciclo único, as CPUs modernas têm várias unidades, cada uma das quais pode executar operações em paralelo, mas são otimizadas para suas próprias situações específicas. De fato, depois de levar em conta as instruções do SIMD , como SSE ou os gráficos integrados à CPU do Sandy Bridge ou CPUs posteriores, pode haver muitas dessas unidades de divisão de ponto flutuante na sua CPU.

Se a divisão de ponto flutuante genérica fosse mais importante para as CPUs modernas, talvez faça sentido dedicar área de silício suficiente para torná-lo um ciclo único, no entanto, a maioria dos fabricantes de chips decidiu obviamente que pode fazer melhor uso desse silício usando esses portões para outras coisas. . Portanto, uma operação é mais lenta, mas no geral (para cenários de uso típico) a CPU é mais rápida e / ou consome menos energia.

Mark Booth
fonte
Que eu saiba, nenhum chip possui latências de divisão de ciclo único para ponto flutuante. Por exemplo, as tabelas de instruções da Agner Fog para os processadores Intel, AMD e VIA listam DIVPS (divisão de ponto flutuante compactado pelo SSE) como 10 a 14 ciclos. Não consigo encontrar nenhum hardware com instruções de divisão de ciclo único, mas gostaria de provar que estou errado. Não é comum, tanto quanto eu posso dizer.
Bill Barth
@ Bill - Obrigado, você está certo. Tenho certeza de que já vi operações de divisão de ciclo único em chips DSP antes, então presumi que teria chegado ao desktop, assim como a multiplicação por ciclo único, mas não consigo encontrar nenhuma referência agora. Atualizei minha resposta e adicionei algumas informações relevantes sobre métodos não iterativos que podem permitir isso no futuro. É incrível pensar que a divisão não é mais eficiente por ciclo agora do que quando eu estava usando transputadores.
Mark Booth
1
Acho que os DSPs fazem isso limitando o intervalo em que são precisos. Essa é a mesma estratégia usada para pesquisa + interpolação para raiz quadrada.
precisa saber é o seguinte
1
Não tenho certeza de qual seria a latência dessa divisão. A 4 GHz, fazer uma viagem de ida e volta à tabela de consulta dentro de N ciclos limita severamente o tamanho potencial da referida tabela (por exemplo, os caches L1 estagnaram em 32 K cada). Tornar-se 3D ajudaria a aumentar isso (mas é um desafio para o resfriamento). Você tem alguma idéia de qual latência poderia ser alcançada para as modernas CPUs 4GHz / 5GHz?
Matthieu M.
1
Para obter números de latência e taxa de transferência divps / divpd vs. mulps / mulpd, consulte Divisão de ponto flutuante versus multiplicação de ponto flutuante . Peguei os dados das tabelas de instruções da Agner Fog e os formatamos em um resumo através de uarches de taxa de transferência div e mul e latência, para simples versus duplo e para diferentes larguras de vetores SIMD. (Chips Intel normalmente têm um divisor de SIMD que é apenas metade da largura da outra ALUs vetor.)
Peter Cordes