Der Pentium Bug Vortrag: Boris Ljepoja Ausarbeitung: Thomas Pfennig & Stefan Rosenegger 30. Oktober 2002 Was ist der Bug? • Fließkommadivision kann falsche bzw. ungenaue Ergebnisse liefern • Abhängigkeit von den Eingabewerten • Fehler frühestens ab der vierten (Dezimal-)Stelle Überblick • • • • • Zeitlicher Hergang SRT-Divisionsalgorithmus Look-up-Tabelle Entstehung eines Fehlers Bitmuster Vorgeschichte • Ende 1993: Markteinführung des Intel Pentium™ als 486-Nachfolger • Bis dahin umfangreichste MarketingKampagne um neuen Markennamen „Pentium“ bekannt zu machen • U.a. schnellerer Dividierer in der FPU, 5x schneller als 486 gleichen Takts Zeitlicher Hergang Entdeckung: • 1994 Prof. Thomas Nicely untersucht numerisch Primzahleigenschaften • Pentium-System liefert abweichende Ergebnisse • Juni 94: Ursachenlokalisation in FPU des Pentium (Befehl FDIV) nach Elimination aller übrigen Fehlerquellen Nicelys Bsp.: 1/ 824633702441 (ab der 8. Stelle falsch) Zeitlicher Hergang • 24. Oktober: Nicely kontaktiert Intel • Intel ohne Lösung, neuere Chips durch Revision aber fehlerfrei • 30. Oktober: Nicely fragt in verschiedenen Foren nach Lösungsvorschlägen • Nicely unterzeichnet NonDisclosure Agreement mit Intel Coes Funktionsmodell Timothy Coe, FPU Designer, entwickelt ein Modell des FP-Dividierers • Genaue Aussagen über die auftretenden Fehler: - Entstehung eines Fehlers - Bestimmung kritischer Operanden - Wahrscheinlichkeiten für Fehlerauftreten • Fehler ermöglicht Einblick in die Funktionsweise des Pentium-FDIV Fehlerhäufigkeit • Vaughan Pratt führt basierend auf Coes Modell empirische Untersuchungen durch • 1 Million Divisionen ganzzahlige Eingabegrößen {1...1000} • 627 fehlerhafte Ergebnisse, davon 427 mit einem relativen Fehler größer als 10-7 und 14 größer als 10-5 Ausmaß • Extrembeispiel: 4195835 : 3145727 = 1,33382045 f(x,y) = x - (x/y)∙y f(4195835,3145727) = (korrekt) =0 = 1,33373907 = 256 (fehlerhafter Pentium) • relativer Fehler ≈ 6∙10-5 • vermutlich größtmöglicher Fehler 3D-Fehlerdarstellung Wahrscheinlichkeiten Firmenanalysen: • INTEL: P(FDIV-Error) = 1 : 9 Mio. - zufällig verteilte Daten - 15 min intensiver FPU Nutzung täglich => ein Fehler alle 27 000 Jahre • IBM: - eine FDIV-Instruktion pro 1000 Maschinentakte => ein Fehler alle 28 Tage • Pratt: - Verwendung problematischer Operanden - häufige Divisionen => mehr als ein Fehler pro Millisekunde Verhalten bei Intel • 27. November 1994: Intel räumt unter Vorbehalt „gefährdeten“ Kunden nach Prüfung der Berechtigung ein Umtauschrecht ein • „Nicht alle User seien von der Ungenauigkeit betroffen, und wenn, dann sei es vertretbar“ Folgen • Pentiumbesitzer verstehen die Haftungsausschluss-Politik bzw. selektiven Umtauschaktionen nicht • Medien berichten ausführlich, so dass Empörung weit über die „Computer-Welt“ hinaus herrscht • Mitte Dezember: Intel versucht Rufschädigung zu begrenzen und bietet bedingungslosen Austausch aller defekten Pentium CPUs an Non-Restoring-Division Restoring-Division Probesubtraktion des Divisors: – Positives Ergebnis = Weiterrechnen – Negatives Ergebnis = Ursprünglichen Wert wiederherstellen (restore) & neue Subtraktion Non-Restoring-Division Akzeptierung von negativen Resten und spätere Korrektur Schuldivision 17 : 4 = 4,25 = 4∙100 + 2∙10-1 + 5∙10-2 + 0∙10-3 + … - 16 ← „Shift“ um eine Dezimalstelle 10 -8 ← „Shift“ um eine Dezimalstelle 20 - 20 – Bezeichnungen p Dividend d Divisor q Quotient pk Divisionsrest im (k+1)-ten Schritt qk Quotientenbit im (k+1)-ten Schritt o.B.d.A.: 1 ≤ p, d < 2 (Radix 4) Divisionsalgorithmus Basis r: r =(2a 10:+1 ≥ r) p0 := p for k = 0,1,... { {-a,...,0,...,a} Wähle Quotientenziffer qk є {0,...,9} als Funktion von pk und d, so dass gilt: r (pk - qk∙d) pk+1 := 10 adr/ |p pk+1|є≤[0,10d[ (r-1) } -1 -1 -2 p/ = q + q ∙10 -2...+ ... ∙r + q ∙r + + q ∙10 q 0 1 2 2 Radix 4-SRT-Division Basis r = 4 p0 := p for k = 0,1,... { Wähle Quotientenziffer qk є {-2,-1,0,1,2} als Funktion von pk und d, so dass gilt: pk+1 := 4(pk - qk∙d) |pk+1| ≤ 8/3d } p/ = q + q ∙4-1 + q ∙4-2 + ... q 0 1 2 Radix 4-SRT-Division Bedingungen für Korrektheit: pk+1 := 4(pk - qk∙d) |pk+1| ≤ 8/3d Gültige (nicht eindeutige) Darstellung von p/d: p/ = q .q q q q q ... (Basis 4) d 0 1 2 3 4 5 Radix 4-SRT-Division Vorteile: • Multiplikation mit {-2,-1,0,1,2} einfach auf Rechnern realisierbar • Redundanz ermöglicht Berechnung zweier (binärer) Quotientenbits in einem Takt • Kompatibilität mit rechnerüblicher Carry-Save-Addition Ziffernauswahl • Bestimmung der aktuellen Quotientenziffer aus 2-dim PD-Table • Indizierung durch Näherungswerte für d (fest) und pk (variabel) • Festlegung: D = x.yyyy P = xxxx.yyy D ≤ d < D+ = D + 1/16 Pk ≤ pk < Pk + 1/4 Auswahlfunktion Look-up-Table: grün blau violett rot braun ~ ~ ~ ~ ~ 2 1 0 -1 -2 FDIV D := floor1/16[d]; for k = 0,1,...,N { Pk := floor1/4[pk]; qk := table-lookup(Pk,D); Berechne (-qkd) über Nullierung oder Shift und/oder 1-Komplement; pk+1 := 4(pk + (-qkd)); // 2x Shift Korrigiere 1-Komplement falls qk < 0 durch Einfügen von „1“ am LSB von ck+1 } p/ = q + q ∙4-1 + q ∙4-2 + ... + q ∙4-N q 0 1 2 N Physische Ursache • 5 Einträge am oberen Ende des erreichbaren Bereichs des PLA sind fehlerhaft • Zellen wurden bei der Produktion mit „0“ anstelle der korrekten „2“ belegt • Auslesen der falschen Werte produziert fortschreitend falsche Quotientenbits Physische Ursache • Steuerungsskript übertrug nur 1061 von 1066 Einträgen des Entwurfs • Grund war laut Intel zu kurze FORSchleife • Fehlerhafte Einträge entsprechen unterer Schranke für Obergrenze • Korrespondenz mit 5 unerreichbaren Einträgen am anderen Ende Fehlercharakteristika • Kritische Divisorwerte: 2/ D = n∙1/ mit n є {1,2,...} 3 + 8 D = 17/16 = 1.0001 D = 20/16 = 1.0100 D = 23/16 = 1.0111 D = 26/16 = 1.1010 D = 29/16 = 1.1101 • Fehlerhafte Einträge: PBad = 8/3D+ - 1/8 Erreichbarkeit • PBad nur vom Eintrag unmittelbar unterhalb (Foothold) erreichbar • Foothold nur auf vier Wegen erreichbar Beschreibung Symbol Wert oberes Ende q = - 2 Bereich P-2 max - 1/4 - 4/3D+ oberes Ende q = - 1 Bereich P-1max - 1/4 - 1/3D+ Eintrag unterhalb Foothold PBad - 1/4 - 3/8 + 8/3D+ Foothold PBad - 1/8 - 1/4 + 8/3D+ Fehlerentstehung • nur erstere beiden Wege können über Foothold unmittelbar im folgenden Schritt zu PBad führen • Fehlerentstehungsmuster P: P-2max/P-1max → PBad - 1/8 → PBad q: - 2/- 1 → 2 → 0 Bitmuster • Erreichen des Footholds führt nicht zwingend zu PBad • Fehlerentstehung funktioniert nur mit bestimmten Bitmustern • Notwendiges Bitmuster: d = d1d2d3d4... d1 bis d4 ergeben kritischen Divisor d5 bis d10 müssen „1“ sein Bitmuster • Analyse der Bitmuster zeigt: frühestens im 7. Schritt kann zum ersten Mal qk < 0 auftreten • Fehler kann daher frühestens im 9. Schritt entstehen (q0 bis q7 stets korrekt) • Ursache für obere absolute Fehlerschranke bei ca. 5∙10-5, meist deutlich darunter Erfahrungen • Immenser Imageschaden für Intel • Kosten für Austauschaktion lagen bei $464 Mio. • Pentium späterer Baureihen nach Revision korrigiert • „The bug in the Pentium was an easy mistake to make, and a difficult one to catch.“ Carry-Save-Addition • Speicherung der Übertragbits in zusätzlichem „carry-word“ • Vermeidung der „carry-propagation“ • Darstellung des Rests im Carry-SaveFormat: pk = sk + ck Divisionsrest • Bestimmung des neuen Näherungswertes Pk+1 durch: Pk+1 := 4(Pk - qkD+) + Rk max • Korrekturterm Rk ≤ Rk : max q = 2: Rk = 5/4 q = 1: Rkmax = 1 max q = 0: Rk = 7/8 max q = 1: Rk = 3/4 max q = 2: Rk = 3/4