andre_teprom escreveu:Marcelo Samsoniuk escreveu:...que calculava o reciproco c = 1/b e entao usava a*c, justamente pq o calculo do reciproco alem de demorar 14x mais, era muito raramente utilizado...
Agora é que entendi o que você quiz dizer com o tal
recíproco, mas confesso que foi por dedução.
Nada mais é que a busca de valores numa tabela ( look-up table ), mas isso não é propriamente um cálculo.
Além disso, quanto maior fosse a precisão necessária, mais gigantesca teria de ser a magnitude da memória.
+++
com lookup table daria para fazer a/b em dois clocks: 1 clock para achar c=1/b e 1 clock para fazer a*c. mas a lookup table teria que ser proporcional ao tamanho do inteiro: para 16 bits, teria 128KB, o que eh um grande desperdicio. provavelmente seria possivel ter uma lookup table menor e interpolar, mas a perda de precisao eh obvia. ao inves disso, existe um metodo que eu acho bem interessante, eh o metodo que costuma ser utilizado para multiplicar por microcodigo, que no caso consiste em um loop com shift e add. por exemplo 1100 x 1001, vc tem 1100 q eh o valor a ser multiplicado e entao multiplica bit a bit pelo outro operando:
1100 x 0001 = 00001100
1100 x 0000 = 00000000
1100 x 0000 = 00000000
1100 x 1000 = 01100000
na pratica o outro operando bit a bit eh sempre um valor 2^n, portanto vira um shift. somando os resultados vc tem o resultado final: 01101100. e de fato, 0xc x 0x9 = 0x6c. se tiver poucos recursos, implementa passo a passo (shift + add) e 16x16=32 bits vao resultar em 16 clocks. se tiver hardware suficiente, pode fazer em paralelo, em um clock.
no caso da divisao, temos um shift e sub, por exemplo 01101100 / 1100, teriamos que shiftar o cara que divide para ter as parcelas e subtrair condicionalmente do cara a ser dividido:
01101100 - 01100000 = 00001100 -> mascara = 1000 -> q = 1000
00001100 - 00110000 menor q zero, mascara 0100 descartada
00001100 - 00011000 menor q zero, mascara 0010 descartada
00001100 - 00001100 = 00000000 -> mascara = 0001 -> q = 1001
e temos 01101100 / 1100 = 1001. bom, em uma primeira instancia, nao vejo como paralelizar isso, entao tem q ir na sequencia, com os shifts e subs condicionais. se imaginar 32/16=16 bits, daria para trabalhar deterministicamente com 16 clocks. nao me parece tao ruim em termos de performance e nao gasta tanta memoria quanto uma lookup table. daria ateh p/ juntar as duas coisas: monta uma cache de reciprocos, consumindo uma fracao do tamanho da lookup table: se o numero esta na cache, ele obtem em 1 clock, senao ele calcula e armazena na cache. assim a divisao a/b com ambos variaveis seria de 1 a 16 clocks para achar c = 1/b e entao 1 clock para fazer a*c.