x87
Az x87 az x86-os architektúrájú processzorokhoz kapcsolódó – külső vagy belső – matematikai társprocesszorok ill. feldolgozóegységek utasításkészletének és az ahhoz kapcsolódó architekturális elemek leírásának jelölésére szolgáló rövidítés. Az „x87” rövidítés az Intel 8087-es koprocesszor jelöléséből ered – az Intel ennek utódjait is rendre 87-re végződő számokkal jelölte. A matematikai társprocesszorok célja elsősorban a lebegőpontos számítások hardveres gyorsítása (a lebegőpontos egység fixpontos és egész adatokkal is dolgozhat), ezáltal az x87-es utasításkészlet a társprocesszor által támogatott adatformátumokon végezhető műveleteket tartalmazza.
A 8087-es és társai kezdetben különálló egységek voltak, amelyek nem voltak képesek önálló működésre és programok futtatására, csak egy megfelelő x86-os architektúrájú processzorhoz kapcsolva működhettek, az x87 tehát eleinte egy utasításkészlet-kiterjesztést jelentett. Később, az i486-os processzorok és az x86-os utasításkészlet 32 bites kiterjesztésének megjelenésével a lebegőpontos egységet beépítették a processzorba, így ettől fogva az x87 az x86-os utasításkészlet egy jól elkülöníthető részét, ill. részhalmazát jelenti.
A 8087-es matematikai processzor kifejlesztésének célja egy olyan, a már meglévő Intel 8231 és Intel 8232 lebegőpontos egységeknél (és a konkurens AMD megegyező termékeinél) nagyobb tudású processzor létrehozása volt, amely szorosabban kapcsolódik az x86-os architektúrához és az Intel által 1977-ben kezdeményezett IEEE 754 szabványhoz. Az 1980-ban elkészült 8087-es processzor volt az IEEE 754 szabvány első, bár nem teljes, fizikai megvalósítása. Az új architektúra megőrizte az elődök (8231, 8232) egyes elemeit, pl. a regiszterek veremstruktúrába való szervezését és egyes adatformátumokat, azonban számos új utasítást kapott és 80 bitre kiterjesztett (ezáltal megnövelt pontosságú) belső adatformátumot tartalmaz.
Leírás
Az x87 regiszterei egy nem szigorúan vett veremstruktúrát alkotnak, amelyben a regisztereket ST(0)-tól ST(7)-ig számozzák. A regiszterek elsősorban a push (behelyezés a verembe) és pop (kivétel a veremből) műveletekkel kapnak értéket, de operandusként közvetlenül is elérhetők, a verem tetejétől számított indexeléssel (ez valamennyire hasonlít pl. a veremkeret kitöltésére a folytonosan címezhető memóriában).
A verem tartalma a push, pop műveletekkel változtatható, de azt a számítások is megváltoztatják. A monadikus utasítások, mint pl. a FSQRT, FPTAN és továbbiak, beleértett módon az ST(0) regiszter tartalmán végzik el a műveletet, míg a diadikus műveletek – FADD, FMUL, FCOM és mások – az ST(0) és ST(1) regiszterekkel végzik el a műveletet. A nem szigorú veremmodell megengedi, hogy a diadikus műveletek az alapértelmezett két regiszteren kívül a második operandus (ami alapértelmezésben az ST(1)) szerepében memóriaoperandust vagy explicit módon meghatározott veremregisztert (ST(x)) használjanak, ilyenkor az ST(0) a megszokott akkumulátor-regiszterhez hasonlóan működik, tehát ez szolgáltatja a művelet első operandusát és az eredmény is ebbe kerül. Ez a címzési szerepkör utasításonként meg is fordítható, amikor az eredmény az ST(x) regiszterbe kerül és az ST(0) értéke változatlan marad. Ezen felül az FXCH ST(x) utasítással az ST(0) tartalma felcserélhető egy másik ST(x) veremregiszter tartalmával.
Az x87 verem ezáltal hét szabadon hozzáférhető regiszter és egy kijelölt akkumulátor (vagy megfordítva: hét kijelölt akkumulátor) használatát teszi lehetővé. Ez nagyon jól kihasználható a szuperskalár x86 processzorokban (mint pl. az 1993-as és későbbi Pentium processzorok), amelyekben ezeket az (D9C8..D9CFh kódú) FXCH ST(x) cserélőutasításokat egészen nulla órajel alatt végrehajthatóvá optimalizálták, az FPU utasításokkal párhuzamosan végrehajtható egészértékű adatutak felhasználásával. Annak ellenére, hogy ez a rendszer az emberi gépi kódú programozók számára természetes és kényelmesen használható, a fordítóprogram-íróknak nehézséget okozott az x87 utasításokat hatékonyan ütemező automatikus kódgenerátorok készítése. Egy ilyen veremalapú interfész képes lehet minimalizálni az átmeneti értékek tárolására fordított tár- v. regiszterhasználatot a függvényhívásokban, szemben a regiszteralapú interfészekkel,[1] annak ellenére, hogy az eredeti tervezési meggondolások erősen korlátozták ezt a lehetőséget az elkészült eszközben.[2][3]
Az x87 architektúra az egyszeres pontosságú bináris lebegőpontos, a dupla pontosságú bináris lebegőpontos és a 80 bites kiterjesztett pontosságú (v. kiterjesztett duplapontos) bináris lebegőpontos adatábrázolási formátumokat és az azokon végzett műveleteket támogatja, az IEEE 754-1985 szabvány szerint. Alapértelmezésben az x87-es processzorok a 80 bit széles kiterjesztett-duplapontos adatformátumot használják belső adatformátumként, ami lehetővé teszi a pontosság fenntartását a sorozatos számításokban – ez egyike volt az IEEE 754 tervezési irányelveinek. A műveletek egy meghatározott sorozata ezért kissé eltérő eredményekre vezethet a szigorúan egyszeres vagy duplapontos adatformátumokkal dolgozó IEEE 754-szabványú matematikai processzorokban.[4] Ez néha problémákat is okozhat bizonyos nem teljesen numerikus számításoknál, amelyekben feltételezik a dupla pontosságot a helyes működés érdekében: hogy ezeket a problémákat elkerüljék, az x87-es processzorok egy speciális konfigurációs regiszter segítségével beállíthatók úgy, hogy minden elvégzett művelet után automatikusan egyszeres vagy dupla pontosságúra kerekítsék az eredményt. Az SSE2 bevezetése után az x87-es utasítások jelentősége csökkent, de továbbra is fontos maradt, mint a kerekítési hibákra érzékeny és a 80 bites adatformátum 64 bites mantisszáját (szignifikandusát) kihasználó számításokat hatékonyan végző skaláris számítóegység.
Teljesítmény
Az alábbi táblázatban tipikus x87-es FPU-utasítások órajelei láthatók, csak a regiszter-regiszter címzésű utasítás-változatokhoz.[5]
Az A~B jelölés minimum-maximum értéket jelöl és átfogja a különböző átmeneti futószalag-állapotokat és a használható adatábrázolási pontosságot (32, 64 vagy 80 bit), és változhat a választott numerikus eset függvényében is (pl. beállított bitek száma, nulla stb.). Az L→H jelölés a legkisebb (L) és legnagyobb (H) alkalmazott órajelet jelenti.
x87 implementáció | FADD | FMUL | FDIV | FXCH | FCOM | FSQRT | FPTAN | FPATAN | Max órajel | FMUL/s[6] csúcsérték | 5 MHz-es 8087§ FMUL műv.hez viszonyított érték |
---|---|---|---|---|---|---|---|---|---|---|---|
8087 | 70~100 | 90~145 | 193~203 | 10~15 | 40~50 | 180~186 | 30~540 | 250~800 | 5→10 MHz | 34~55K → 100~111K | 1.0 → 2.0-szer gyorsabb |
80287 (eredeti) | 70~100 | 90~145 | 193~203 | 10~15 | 40~50 | 180~186 | 30~540 | 250~800 | 6→12 MHz | 41~66K → 83~133K | 1.2 → 2.4-szer gyorsabb |
80387 (és későbbi 287 modellek) |
23~34 | 29~57 | 88~91 | 18 | 24 | 122~129 | 191~497 | 314~487 | 16→33 MHz | 280~552K → 579~1100K | kb. 10 → 20 × gyorsabb |
80486 (vagy 80487) | 8~20 | 16 | 73 | 4 | 4 | 83~87 | 200~273 | 218~303 | 16→50 MHz | 1.0M → 3.1M | kb. 18 → 56 × gyorsabb |
Cyrix 6x86, Cyrix MII | 4~7 | 4~6 | 24~34 | 2 | 4 | 59~60 | 117~129 | 97~161 | 66→300 MHz | 11~16M → 50~75M | kb. 320 → 1400 × |
AMD K6 (K6 II/III is) | 2 | 2 | n.a. | 2 | n.a. | n.a. | n.a. | n.a. | 166→550 MHz | 83M → 275M | kb. 1500 → 5000 × |
Intel P5 / Pentium / Pentium MMX |
1~3 | 1~3 | 39 | 1 (0*) | 1~4 | 70 | 17~173 | 19~134 | 60→300 MHz | 20~60M → 100~300M | kb. 1100 → 5400 × |
Pentium Pro | 1~3 | 2~5 | 16~56 | 1 (0*) | 1 | 28~68 | n.a. | n.a. | 150→200 MHz | 30~75M → 40~100M | kb. 1400 → 1800 × |
Pentium II / III | 1~3 | 2~5 | 17~38 | 1 (0*) | 1 | 27~50 | n.a. | n.a. | 233→1400 MHz | 47~116M → 280~700M | kb. 2100 → 13000 × |
Athlon (K7) | 1~4 | 1~4 | 13~24 | 1 (0*) | 1~2 | 16~35 | n.a. | n.a. | 500→2330 MHz | 125~500M → 0.580~2.33G | kb. 9000 → 42000 × |
Pentium 4 | 1~5 | 2~7 | 20~43 | több ciklus | n.a. | 20~43 | n.a. | n.a. | 1.3→3.8 GHz | 186~650M → 0.543~1.90G | kb. 11000 → 34000 × |
Athlon 64 (K8) | 1~4 | 1~4 | 13~24 | 1 (0*) | 1~2 | 16~35 | n.a. | n.a. | 1.0→3.2 GHz | 250~1000M → 0.800~3.2G | kb. 18000 → 58000 × |
* Effektív nulla órajelű végrehajtási idő lehetséges, a szuperskalár végrehajtás következményeként.
§ Az eredeti x87-es processzor az 5 MHz órajelű 8087 volt. (Hasonló órajelű, 8087 nélküli) 8086-os processzoron szoftveresen megvalósított lebegőpontos rutinokkal összehasonlítva a szorzók sokkal nagyobbak lehetnek, kb. tízszeresek (pl. egy szabályos lebegőpontos összeadás assembly nyelven meghaladhatja az 1000 órajelciklust).
(n.a.: nincs adat)
Gyártók
Az Intel 8087 vagy későbbi modellekkel kompatibilis lebegőpontos egységeket terveztek és/vagy gyártottak még a következő cégek (a felsorolás nem teljes):
AMD (287, 387, 486DX, 5x86, K5, K6, K7, K8), Chips and Technologies (Super MATH koprocesszorok), Cyrix (FasMath, Cx87SLC, Cx87DLC stb., 6x86, Cyrix MII), Fujitsu (a korai Pentium Mobile stb.), Harris Semiconductor (80387 és 486DX processzorokat is gyártott), IBM (különféle 387 és 486 kialakítások), IDT (a WinChip, C3, C7, Nano stb.), IIT (a 2C87, 3C87 modellek), LC Technology (a Green MATH koprocesszorok), National Semiconductor (a Geode GX1, Geode GXm stb.), NexGen (az Nx587), Rise Technology (az mP6), ST Microelectronics (486DX, 5x86 stb. gyártó), Texas Instruments (486DX processzorok stb. gyártó), Transmeta (a TM5600 és TM5800), ULSI (a Math·Co koprocesszorok), VIA (a C3, C7 és Nano stb.), és az Xtend (a 83S87SX-25 és más koprocesszorok gyártója).
Architekturális nemzedékek
8087
A 8087-es volt az első „matematikai koprocesszor” ill. társprocesszor, amelyet az Intel 16 bites processzorai mellett való működésre terveztek (egyik elődje, az Intel 8231 8 bites processzorokkal működött együtt); tehát a 8087-es az Intel 8088 vagy 8086 processzorokkal működött együtt.
80187
A 80187 (80C187)[7] az Intel 80186 CPU-hoz kapcsolható matematikai társprocesszor. A 80188-as processzorral nem képes együttműködni, mivel annak adatbusza 8 bites; a 80188-as csak a 8087-es koprocesszort használhatja. A 80187 nem a 80186-os és 80188-as processzorokkal egyidőben jelent meg, hanem a 80287-es és 80387-es megjelenése után készült. Bár a főprocesszor felé kialakított interfész-felülete megegyezett a 8087-esével, magja egy 80387-es volt és ezáltal teljesen megfelel az IEEE 754 szabványnak, és végrehajtja a 80387-es extra utasításait is.[8]
80287
A 80287 (i287) az Intel 80286 sorozat processzoraihoz illeszkedő matematikai társprocesszor. Az Intel-gyártmányú modellek órajelének felső határa 6-tól 12 MHz-ig terjedt. Később elkészült az i80287XL, amely 387-es mikroarchitektúrával rendelkezett, és az i80287XLT, amely egy különleges, laptopokba szánt modell; és még néhány egyéb változat.
A 80287XL jelű modell valójában egy 80387SX, a 287-es lábkiosztásának megfelelő kiszerelésben. Ez egy belső 3/2 arányú szorzót tartalmaz, hogy azokban az alaplapokban, amelyek a koprocesszort a főprocesszor órajelének 2/3-ára csökkentett sebességen hajtják, a koprocesszor a CPU-val azonos sebességen működjön. További 387-eshhez hasonló teljesítményű 287-es modellek pl. a CHMOS III technológiával gyártott Intel 80C287, és az AMD 80EC287, amely az AMD CMOS folyamatával készült és teljesen statikus kapukat tartalmaz.
A 80287 és 80287XL a 80386-os processzorral működik együtt; ez volt a 80386-oshoz illeszthető teljes koprocesszor-választék egészen a 80387-es megjelenéséig 1987-ben. Szintén ezek kapcsolódhattak a Cyrix Cx486SLC processzorhoz. A 80387-es nagyobb teljesítménye és utasításkészlete miatt népszerűbb lett ezeknél.
80387
A 80387 (másként 387 vagy i387) volt az első Intel koprocesszor, amely teljesen megfelelt az IEEE 754 szabványnak. 1987-ben bocsátották ki, két évvel a 386-os processzor megjelenése után. Az i387-es csip sebessége jóval felülmúlta a 8087/80287 koprocesszorok sebességét, és javított trigonometriai funkciókkal bővült (a 287-esnél az értelmezési tartomány korlátozott, −45-től +45 fokig terjed).
A koprocesszor nélküli 386-os rendszerben a processzor lassú szoftveres rutinok segítségével végzi a lebegőpontos számításokat, amelyeket a futási időben egy szoftverkivétel-kezelőn keresztül hív meg. Egy 386-os a hozzá kapcsolt matematikai koprocesszorral ettől eltérő módon működik: a koprocesszor végzi a lebegőpontos műveleteket a hardverében, és az eredményeket visszaadja a főprocesszornak, mindezt sokkal gyorsabban, mint az emulációs szoftver könyvtári függvényeinek hívása.
Az i387 csak a szabványos i386-os csippel kompatibilis, amelyben a processzor rendszersíne 32 bites. A későbbi csökkentett árú i386SX típust egy keskenyebb 16 bites adatsínnel szerelték, így nem volt képes együttműködni az i387-essel, a 32 bites sín miatt. Az i386SX saját különbejáratú koprocesszorát igényelte, ez volt a 80387SX, amely az SX keskenyebb 16 bites adatsínjéhez volt illesztve.
-
i387
-
i387SX
-
i387DX
-
i386DX és egy i387DX
80487
Az i487SX modell marketingje szerint az Intel i486SX processzorokkal szerelt gépek lebegőpontos egysége volt; valójában azonban ez egy teljesen kiépített i486DX egység, tehát tartalmazza a processzorba épített integrált FPU-t. Amikor egy i486SX típusú rendszerbe helyezik, az i487-es letiltja a fő processzor működését és átveszi az összes CPU-műveletet. Bár az Intel tett bizonyos lépéseket, amelyek megkövetelték egy i486SX processzor jelenlétét az i487SX szabályos működéséhez, mégis elismerte, hogy egyes rendszerek működhetnek i486SX egység nélkül is. Az Intel azonban arra figyelmeztet, hogy az ilyen konfigurációk helyes működése nem garantált.[10]
80587
Az Nx587 volt az utolsó, CPU-tól külön egységként gyártott FPU az x86 sorozatú processzorokhoz, amely ebben az esetben a NexGen Nx586 jelű processzora volt.
Jegyzetek
- ↑ William Kahan: On the advantages of 8087's stack. Unpublished course notes, Computer Science Division, University of California at Berkeley., 1990. november 2. [2013. június 12-i dátummal az eredetiből archiválva]. (Hozzáférés: 2013. szeptember 23.)
- ↑ William Kahan: How Intel 8087 stack overflow/underflow should have been handled., 1989. július 8. [2013. június 12-i dátummal az eredetiből archiválva]. (Hozzáférés: 2013. szeptember 23.)
- ↑ Jack Woehr: A conversation with William Kahan., 1997. november 1.
- ↑ David Monniaux, The pitfalls of verifying floating-point computations, to appear in ACM TOPLAS
- ↑ A számok az adott processzor adatlapjairól, programozási kézikönyvéből vagy optimalizálási kézikönyvéből származnak.
- ↑ lebegőpontos szorzás / másodperc
- ↑ CPU Collection - Model 80187. [2011. július 23-i dátummal az eredetiből archiválva]. (Hozzáférés: 2013. szeptember 23.)
- ↑ http://www.datasheetcatalog.org/datasheet/Intel/mXryvuw.pdf
- ↑ állítható lépésméretű léptetőregiszter
- ↑ Intel 487SX (angol nyelven). (Hozzáférés: 2010. október 17.)
Fordítás
Ez a szócikk részben vagy egészben a x87 című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.
Források
- 8087 (80287) ARITMETIKAI PROCESSZOROK – ALKALMAZÓI SEGÉDLET, feldolg. Lédeczi Tamás, témafel. Makra Ernőné, lektor: Kiss Klára, Saufert János (magyar nyelven), Budapest: Ipari Információs Központ, 1–133. o. [1987]. ISBN 963-02-4292-3. Hozzáférés ideje: 2013.
További információk
- Coprocessor.info : az x86 koprocesszor fejlesztése és története
- Everything you always wanted to know about math coprocessors