Ken Shirriff è un ingegnere informatico, blogger e reverse engineer noto per i suoi approfondimenti sull’hardware e sul software utilizzati nei sistemi che hanno fatto la storia dell’informatica. Il ricercatore ha appena concluso uno studio sui segreti dello storico processore Intel Pentium, dettagliando la scoperta di un curioso circuito che moltiplica per 3 massimando le prestazioni rispetto a qualunque altro possibile approccio alternativo.
Quando, nel 1993, Intel lanciò il suo rivoluzionario Pentium, non si limitò a immettere sul mercato un chip più veloce. Shirriff ha scoperto un piccolo capolavoro di ingegneria: un circuito dedicato alla moltiplicazione per 3. Può sembrare banale, ma questo “moltiplicatore x3” è un esempio brillante di come gli ingegneri spingono i limiti della tecnologia per ottenere prestazioni estreme.
Perché preoccuparsi tanto del numero 3?
La ragione si trova nel cuore dell’unità a virgola mobile del Pentium, l’area del chip responsabile dei calcoli numerici complessi, come quelli necessari per la grafica 3D. Per accelerare questi calcoli, il Pentium utilizza una tecnica chiamata moltiplicazione in base 8.
Immaginate di raggruppare le cifre binarie (0 e 1) a tre a tre, un po’ come lavorare con numeri “ottali” (da 0 a 7) invece di numeri binari. Si tratta di un’astuzia pensata per ridurre il numero di passaggi necessari per eseguire una moltiplicazione complessa.
L’esempio seguente illustra come calcoliamo la moltiplicazione 5×6 in binario: i termini sono sommati per ottenere il risultato.
101 ×110 ――― 000 i.e. 0×101 101 i.e. 1×101 +101 i.e. 1×101 ――――― 11110
Questo approccio di moltiplicazione diretto è tuttavia inefficiente. Con i numeri a tre bit sopra, è necessario sommare tre termini. La moltiplicazione di due numeri a 64 bit, invece, comporterebbe la somma di 64 termini, richiedendo tempo e/o circuiti significativi. Per superare queste limitazioni, il Pentium utilizza l’approccio più sofisticato incentrato sulla moltiplicazione in base 8.
Lo svantaggio della moltiplicazione in base 8 è la complessità della moltiplicazione per un numero da 0 a 7, che supera la semplicità della moltiplicazione per 0 o 1. Fortunatamente, ci sono delle scorciatoie. Moltiplicare per 2 equivale a spostare il numero di 1 bit a sinistra, un’operazione facilmente realizzabile in hardware. Allo stesso modo, per moltiplicare per 4, il moltiplicando è spostato di due posizioni di bit a sinistra.
La moltiplicazione per tre è invece più complessa: l’utilizzo di un semplice sommatore è troppo lento e i riporti rallentano l’operazione di addizione.
Un circuito “turbo” per moltiplicare per 3
Intel ha risolto il problema costruendo un circuito specificamente progettato per moltiplicare rapidamente per 3. Questo circuito, sebbene piccolo (neanche poi così tanto se paragonato con la dimensione del die nel suo complesso), era incredibilmente sofisticato, incorporando tecniche avanzate di progettazione digitale:
- Carry Lookahead: Un sistema per “prevedere” i riporti dell’addizione, permettendo di accelerare i calcoli invece di attendere la propagazione sequenziale dei riporti.
- Parallel Prefix Adder (Kogge-Stone): Un’architettura avanzata che permette di sommare i numeri in parallelo, dividendo il compito in sotto-problemi più piccoli e risolvendoli contemporaneamente.
- Carry Select Adder: Un approccio “doppio binario” in cui vengono calcolati due risultati possibili contemporaneamente (uno assumendo un riporto, l’altro no). Successivamente viene selezionato il risultato corretto in base al riporto effettivo.
Queste tecniche, combinate in un circuito compatto ma potente, hanno permesso al Pentium di eseguire moltiplicazioni per 3 a velocità incredibili. D’altra parte, ogni nanosecondo conta.
Più che un numero, una chiave per le prestazioni
Il moltiplicatore x3 del Pentium non è soltanto un dettaglio tecnico. Ha contribuito in modo significativo alle prestazioni complessive del processore, permettendo una grafica 3D più fluida, calcoli scientifici più rapidi e, in generale, un’esperienza utente più reattiva. Era un esempio di come l’ottimizzazione di un’operazione apparentemente semplice potesse avere un impatto significativo sulle prestazioni di un sistema complesso.
Il supporto hardware per la moltiplicazione ha una lunga storia che risale agli anni ’50. I primi microprocessori, tuttavia, avevano capacità molto limitate: chip come il MOS 6502 non avevano supporto hardware per la moltiplicazione; gli utenti dovevano implementare la moltiplicazione nel software tramite spostamenti e addizioni. Con l’avanzare dell’hardware, i processori fornivano istruzioni a supporto della moltiplicazione, ma erano comunque lenti.
Ad esempio, il processore Intel 8086 (1978) implementava la moltiplicazione nel microcodice, eseguendo internamente un lento ciclo di spostamento e addizione. I processori divennero esponenzialmente più potenti nel tempo, come descritto dalla legge di Moore, consentendo ai processori successivi di includere hardware di moltiplicazione dedicato. Il processore 386 (1985) includeva un’unità di moltiplicazione , ma era comunque lento, impiegando fino a 41 cicli di clock per un’istruzione di moltiplicazione.
All’epoca del Pentium (1993), i microprocessori contenevano milioni di transistor, aprendo nuove possibilità di progettazione. Gli architetti di chip poterono quindi prendere in considerazione nuovi approcci per spremere più prestazioni da un sistema.
Il moltiplicatore x3 scoperto da Shirriff contiene circa 9000 transistor, un po’ più di un intero microprocessore Z80 (1976), ed è soltanto una piccola parte del moltiplicatore in virgola mobile, che fa parte dell’unità in virgola mobile del Pentium. Questo piccolo pezzo di funzionalità è quindi più complicato di un intero microprocessore di 17 anni prima. Cartina tornasole dell’incredibile crescita nella complessità dei processori destinati ai sistemi informatici.
Credit immagine in apertura: Intel