Perché la divisione è molto più complessa di altre operazioni aritmetiche?


39

Recentemente ho riscontrato un caso in cui avevo bisogno di un'operazione di divisione intera su un chip che mancava uno (ARM Cortex-A8). Mentre cercavo di capire perché dovesse essere così, ho scoperto che in generale la divisione richiede molti più cicli di addizione, sottrazione o moltiplicazione su praticamente qualsiasi architettura intera (o fissa). Perché è così? Non è rappresentabile con una logica AND-OR a due livelli come tutto il resto?

Risposte:


34

La divisione è un algoritmo iterativo in cui il risultato del quoziente deve essere spostato sul resto usando una misura euclidea, vedi 2 ; mentre la moltiplicazione può essere ridotta a una serie (fissa) di trucchi per la manipolazione dei bit.


2
In passato, sia la moltiplicazione che la divisione erano operazioni lente. Oggi la moltiplicazione è un po 'più veloce (ma leggermente più lenta di addizione / sottrazione), ma la divisione è ancora più lenta delle altre. Credo che Newton-Raphson sia ancora usato internamente dalla maggior parte per ricambiare un numero.
JM,

12
(Off-topic: "Le operazioni inverse sono di solito difficili. Basta guardare all'integrazione rispetto alla differenziazione." - dipende dal fatto che ciò che stai facendo sia simbolico o numerico. La differenziazione è simbolicamente facile, ma numericamente dura; l'integrazione è simbolicamente dura, ma numericamente facile.)
JM il

1
Okay, farò la guardia dicendo che la cubatura è una lattina diversa di vermi; ma almeno nel caso monodimensionale, la quadratura è più facile della differenziazione.
JM,

1
In ogni caso, le inversioni vengono sempre in coppia. Perché chiameresti uno "operazione" e l'altro "inverso"?
David Ketcheson,

2
Né l'iterazione né l'inverso lo rendono più difficile. La durezza della divisione deriva dal fatto che è necessario spostare il risultato dal quoziente al resto usando una misura euclidea. Vedi il teorema dell'algoritmo di divisione .

20

Mentre tutte le attuali CPU sembrano usare un approccio iterativo come suggerisce aterrel , c'è stato del lavoro fatto su approcci non iterativi. Divisione a virgola mobile e radice quadrata a precisione variabile parla di un'implementazione non iterativa di divisione in virgola mobile e radice quadrata in un FPGA , utilizzando le tabelle di ricerca e l'espansione della serie taylor.

Ho il sospetto che le stesse tecniche possano consentire di ottenere queste operazioni in un singolo ciclo (throughput, se non latenza), ma è probabile che abbiate bisogno di enormi tabelle di ricerca, e quindi di aree impossibili di proprietà immobiliari in silicio per farlo .

Perché non sarebbe fattibile?

Nel progettare CPU ci sono molti compromessi da fare. Funzionalità, complessità (numero di transistor), velocità e consumo di energia sono tutti correlati e le decisioni prese durante la progettazione possono avere un impatto enorme sulle prestazioni.

Un moderno processore probabilmente potrebbe avere un'unità principale in virgola mobile che dedica abbastanza transistor al silicio per eseguire una divisione in virgola mobile in un singolo ciclo , ma è improbabile che sia un uso efficiente di quei transistor.

Il virgola mobile si è moltiplicato per questa transizione da iterativo a non iterativo un decennio fa. In questi giorni, moltiplicare un ciclo e persino moltiplicare-accumulare sono all'ordine del giorno, anche nei processori mobili.

Prima che diventasse un uso efficiente del budget dei transistor, moltiplicare, come la divisione, veniva spesso eseguito con un metodo iterativo. All'epoca, i processori DSP dedicati potevano dedicare la maggior parte del loro silicio a una singola unità di accumulo rapido multiplo (MAC) . Una CPU Core2duo ha una latenza di moltiplicazione in virgola mobile pari a 3 (il valore esce dal ciclo della pipeline 3 dopo che è entrato), ma può avere 3 moltiplicazioni in volo contemporaneamente, risultando in un throughput a ciclo singolo, nel frattempo l'unità SSE2 può pompare moltiplicazioni multiple di FP in un singolo ciclo.

Invece di dedicare enormi aree di silicio a un'unità di divisione a ciclo singolo, le moderne CPU hanno più unità, ognuna delle quali può eseguire operazioni in parallelo, ma sono ottimizzate per le proprie situazioni specifiche. In effetti, una volta che si prendono in considerazione le istruzioni SIMD come SSE o la grafica integrata della CPU del Sandy Bridge o CPU successive, ci possono essere molte di queste unità di divisione in virgola mobile sulla CPU.

Se la divisione in virgola mobile generica fosse più importante per le moderne CPU, potrebbe avere senso dedicare abbastanza area di silicio per renderlo a ciclo singolo, tuttavia la maggior parte dei produttori di chip ha ovviamente deciso che possono usare meglio quel silicio usando quelle porte per altre cose . Pertanto un'operazione è più lenta, ma nel complesso (per scenari di utilizzo tipici) la CPU è più veloce e / o consuma meno energia.


Per quanto ne sappia, nessun chip ha latenze di divisione a ciclo singolo per virgola mobile. Ad esempio, le tabelle di istruzioni di Agner Fog per CPU Intel, AMD e VIA elencano DIVPS (divisione in virgola mobile SSE) come 10-14 cicli. Non riesco a trovare alcun hardware con istruzioni di divisione a ciclo singolo, ma sarei disposto a essere smentito. Non è comune per quanto ne so.
Bill Barth,

@Bill - Grazie, hai ragione. Sono sicuro di aver già visto operazioni di divisione a ciclo singolo nei chip DSP in precedenza, quindi ho pensato che sarebbe arrivato al desktop, proprio come ha fatto con la moltiplicazione a ciclo singolo, ma non riesco a trovare alcun riferimento ora. Ho aggiornato la mia risposta e aggiunto alcune informazioni pertinenti sui metodi non iterativi che potrebbero consentirle in futuro. È sorprendente pensare che la divisione non sia più efficiente per ciclo ora rispetto a quando stavo usando i trasmettitori.
Mark Booth,

1
Penso che i DSP lo facciano limitando l'intervallo in cui sono precisi. Questa è la stessa strategia utilizzata per la ricerca + interpolazione per radice quadrata.
Matt Knepley,

1
Non sono sicuro di quale sarebbe la latenza di tale divisione. A 4 GHz, fare un giro di andata e ritorno alla tabella di ricerca all'interno di N cicli limita fortemente la dimensione potenziale di detta tabella (ad esempio, le cache L1 sono state stagnanti a 32K ciascuna). Passare al 3D aiuterebbe ad aumentare questo (ma è impegnativo il raffreddamento wrt.). Hai idea di quale latenza potrebbe essere raggiunta per le moderne CPU a 4 GHz / 5 GHz?
Matthieu M.

1
Per i numeri di latenza e throughput divps / divpd vs. mulps / mulpd, vedere Divisione in virgola mobile vs moltiplicazione in virgola mobile . Ho preso i dati dalle tabelle di istruzioni di Agner Fog e li ho formattati in un riepilogo attraverso gli archi di throughput e lat div e lat, per singoli o doppi e per diverse larghezze vettoriali SIMD. (I chip Intel in genere hanno un divisore SIMD che è solo metà della larghezza degli altri ALU vettoriali.)
Peter Cordes,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.