Powszechnie stwierdza się, że 64-bitowa architektura procesora Intel Itanium zawiodła, ponieważ rewolucyjny zestaw instrukcji EPIC był bardzo trudny do napisania dobrego kompilatora, co oznaczało brak dobrych narzędzi programistycznych dla IA64, co oznaczało brak programistów tworzących programy dla architektury i dlatego nikt nie chciał używać sprzętu bez dużej ilości oprogramowania, dlatego platforma zawiodła, a wszystko z powodu brakugwóźdź podkowy dobre kompilatory.
Ale dlaczego kompilator był tak trudnym problemem technicznym? Wydaje mi się, że skoro jednoznaczna paralelność w EPIC była trudna do wdrożenia przez dostawców kompilatorów ... po co nakładać na nich takie obciążenie? To nie jest tak, że dobre, dobrze zrozumiałe rozwiązanie tego problemu jeszcze nie istniało: zamiast tego obciążyć Intela i dać twórcom kompilatorów prostszy cel.
Itanium pojawił się w 1997 roku. W tym momencie system kodu bajtowego P-Code UCSD miał prawie 20 lat, maszyna Z była nieco młodsza, a JVM stała się nową wschodzącą gwiazdą w świecie języków programowania. Czy jest jakiś powód, dla którego Intel nie określił „prostego języka bajtowego Itanium” i zapewnił narzędzie, które przekształca ten bajtowy kod w zoptymalizowany kod EPIC, wykorzystując swoją wiedzę jako ludzie, którzy zaprojektowali system w pierwszej kolejności?
Odpowiedzi:
Jak pamiętam, problemem były nie tylko szczegóły IA64, ale także konkurencja z zestawem instrukcji x86-64 AMD. Dzięki temu, że ich architektura jest wstecznie kompatybilna z zestawem instrukcji x86, AMD było w stanie wykorzystać istniejące narzędzia i zestawy umiejętności programistycznych. Ruch AMD był tak udany, że Intel (i Via) zostały zasadniczo zmuszone do przyjęcia architektury x86-64.
Dużą barierą w tym czasie było 4 GB pamięci RAM na komputerach stacjonarnych (bardziej realistycznie ~ 3,4 GB w systemie Windows). Procesor x86-64 zniszczył tę barierę i udostępnił wszystkim większą moc obliczeniową. Gdyby AMD nigdy nie wymyśliło x86-64, jestem pewien, że Intel byłby szczęśliwy, gdyby wszyscy, którzy chcieli przeskoczyć do 4 GB + pamięci RAM, płacili za tę usługę ogromną premię za lata. Pokazując, jak powoli rynki się zmieniają, lata zajęły aplikacjom przechwycenie do 64-bitowego, wielowątkowego programowania, a nawet teraz 4 GB pamięci RAM jest standardem w komputerach z niższej półki.
Krótko mówiąc, Intel próbował dokonać rewolucyjnego skoku w architekturze IA64, a AMD dokonało ewolucyjnego kroku z x86-64. Na ugruntowanym rynku etapy ewolucyjne, które pozwalają pracownikom wiedzy wykorzystać istniejące umiejętności, przekonają rewolucyjne kroki, które wymagają od wszystkich uczenia się nowych umiejętności. Niezależnie od różnic jakościowych między architekturami, IA64 nie był w stanie przezwyciężyć rozpędu własnej platformy x86, gdy AMD dodało rozszerzenia x86-64.
Nie kupuję wyjaśnienia, że program IA64 był zbyt trudny do zaprogramowania. To było tylko trudne w stosunku do alternatyw. Punkt @ delnana na temat IR na niskim poziomie jest bardzo trafny, po prostu nie sądzę, że zrobiłoby to różnicę.
Co, dlaczego Intel nie próbował sobie z tym poradzić, kto wie? Byli wówczas siłą rynkową. AMD stanowiło coś w rodzaju zagrożenia, ale Intel był królem wzgórza. Może myśleli, że IA64 byłby o wiele lepszy niż cokolwiek innego, że mogliby przenieść cały rynek. Być może próbowali stworzyć poziom premium i zostawić AMD, VIA itp. Na drugim poziomie, walcząc o sprzęt o niskiej marży - strategia, którą zarówno Intel, jak i Apple zastosowały z powodzeniem.
Czy Itanium była celową próbą stworzenia platformy premium i wyciągnięcia dywanu spod AMD, VIA itp.? Oczywiście tak działa biznes.
źródło
Artykuł w Wikipedii na temat EPIC przedstawił już wiele zagrożeń wspólnych dla VLIW i EPIC.
Jeśli ktoś nie rozumie fatalizmu z tego artykułu, pozwólcie, że podkreślę:
Innymi słowy, każdy projekt sprzętu, który nie poradzi sobie z (*) niedeterministycznym opóźnieniem dostępu do pamięci, stanie się po prostu spektakularną awarią.
(*) Aby „poradzić sobie z”, konieczne jest osiągnięcie względnie dobrej wydajności wykonania (innymi słowy „konkurencyjnej pod względem kosztów”), co oznacza, że procesor nie musi pozostawać bezczynny przez dziesiątki do setek cykli.
Zauważ, że strategia radzenia sobie zastosowana przez EPIC (wspomniana w artykule w Wikipedii, do którego link znajduje się powyżej) nie rozwiązuje problemu. Mówi jedynie, że ciężar wskazywania zależności danych spoczywa teraz na kompilatorze. W porządku; kompilator ma już tę informację, więc kompilator jest w pełni zgodny. Problem polega na tym, że procesor nadal będzie bezczynny przez dziesiątki do setek cykli w ramach dostępu do pamięci. Innymi słowy, uzewnętrznia wtórną odpowiedzialność, a jednocześnie nie radzi sobie z podstawową odpowiedzialnością.
Pytanie można sformułować następująco: „Biorąc pod uwagę platformę sprzętową, która ma być porażką, dlaczego (1) nie (2) twórcy kompilatora nie mogli podjąć heroicznego wysiłku, aby ją zrealizować?”
Mam nadzieję, że moje ponowne sformułowanie sprawi, że odpowiedź na to pytanie będzie oczywista.
Istnieje drugi aspekt niepowodzenia, który również jest śmiertelny.
Strategie radzenia sobie (wspomniane w tym samym artykule) zakładają, że wstępne pobieranie oparte na oprogramowaniu może być wykorzystane do odzyskania co najmniej części utraty wydajności z powodu niedeterministycznego opóźnienia z dostępu do pamięci.
W rzeczywistości pobieranie wstępne jest opłacalne tylko wtedy, gdy wykonujesz operacje przesyłania strumieniowego (odczytywanie pamięci w sposób sekwencyjny lub wysoce przewidywalny).
(To powiedziawszy, jeśli twój kod zapewnia częsty dostęp do niektórych zlokalizowanych obszarów pamięci, buforowanie pomoże).
Jednak większość oprogramowania ogólnego przeznaczenia musi mieć wiele losowych dostępów do pamięci. Jeśli weźmiemy pod uwagę następujące kroki:
W przypadku większości programów ogólnego zastosowania te trzy muszą być wykonywane szybko po sobie. Innymi słowy, nie zawsze jest możliwe (w ramach logiki oprogramowania) obliczenie adresu z góry lub znalezienie wystarczającej ilości pracy do wypełnienia przeciągnięć między tymi trzema krokami.
Aby wyjaśnić, dlaczego nie zawsze można znaleźć wystarczającą ilość pracy, aby zapełnić stragany, oto jak można to sobie wyobrazić.
(*) Gdybyśmy mogli kiedykolwiek
NOP
zrobić pożyteczną pracę ...Współczesne procesory próbują poradzić sobie z tym samym, wykorzystując informacje dynamiczne - jednocześnie śledząc postęp każdej instrukcji, gdy krążą one w rurociągach. Jak wspomniałem powyżej, część tej dynamicznej informacji wynika z niedeterministycznego opóźnienia pamięci, dlatego nie można przewidzieć z jakimkolwiek stopniem dokładności przez kompilatory. Ogólnie rzecz biorąc, po prostu nie ma wystarczającej ilości informacji w czasie kompilacji, aby podjąć decyzje, które mogłyby wypełnić te stragany.
W odpowiedzi na odpowiedź AProgrammera
Nie jest tak, że „kompilator ... wyodrębnianie równoległości jest trudny”.
Ponowne uporządkowanie pamięci i instrukcji arytmetycznych przez współczesne kompilatory jest dowodem na to, że nie ma problemu z identyfikacją operacji, które są niezależne, a tym samym wykonywalne jednocześnie.
Głównym problemem jest to, że niedeterministyczne opóźnienie pamięci oznacza, że jakiekolwiek „parowanie instrukcji” zakodowane dla procesora VLIW / EPIC zostanie zablokowane przez dostęp do pamięci.
Optymalizacja instrukcji, które nie blokują się (tylko rejestr, arytmetyka) nie pomoże w problemach z wydajnością spowodowanych przez instrukcje, które najprawdopodobniej utkną (dostęp do pamięci).
Jest to przykład niezastosowania zasady optymalizacji 80-20: Optymalizacja rzeczy, które już są szybkie, nie poprawi znacząco ogólnej wydajności, chyba że wolniejsze rzeczy są również optymalizowane.
W odpowiedzi na odpowiedź Basile Starynkevitch
To nie jest „... (cokolwiek) jest trudne”, jest to, że EPIC nie jest odpowiedni dla żadnej platformy, która musi poradzić sobie z wysoką dynamiką w latencji.
Na przykład, jeśli procesor ma wszystkie następujące cechy:
W takim razie VLIW / EPIC będzie dobrze pasować.
Gdzie można znaleźć takie procesory? DSP. I właśnie tam rozkwitła VLIW.
Z perspektywy czasu upadek Itanium (i ciągłe zalewanie wysiłków badawczo-rozwojowych niepowodzeniem, pomimo oczywistych dowodów) jest przykładem niepowodzenia organizacyjnego i zasługuje na dogłębne zbadanie.
To prawda, że inne przedsięwzięcia dostawcy, takie jak hyperthreading, SIMD itp., Wydają się bardzo udane. Możliwe, że inwestycja w Itanium mogła mieć wzbogacający wpływ na umiejętności inżynierów, co mogło umożliwić im stworzenie następnej generacji udanej technologii.
źródło
TL; DR: 1 / istnieją inne aspekty niepowodzenia Itanium niż problemy z kompilatorem i mogą być bardzo wystarczające, aby to wyjaśnić; 2 / kod bajtowy nie rozwiązałby problemów kompilatora.
Spóźnili się (zaplanowano na 98, pierwsza dostawa w 2001 r.), A kiedy w końcu dostarczyli sprzęt, nie jestem nawet pewien, czy dostarczył to, co obiecano na wcześniejszą datę (IIRC, przynajmniej upuścił część emulacja x86, która początkowo była planowana), więc nie jestem pewien, że nawet jeśli problemy z kompilacją zostały rozwiązane (a AFAIK, jeszcze nie), to by się udało. Aspekt kompilatora nie był jedynym aspektem, który był zbyt ambitny.
Nie jestem pewien, gdzie umieścisz narzędzie.
Jeśli jest w procesorze, masz tylko inną mikroarchitekturę i nie ma powodu, aby nie używać x86 jako publicznego ISA (przynajmniej dla Intela, niezgodność ma wyższy koszt niż cokolwiek, co mogłoby przynieść czystszy publiczny ISA).
Jeśli jest zewnętrznie, rozpoczęcie od kodu bajtowego sprawia, że jest to trudniejsze niż rozpoczęcie od języka wyższego poziomu. Problem z EPIC polega na tym, że może on korzystać tylko z równoległości, którą może znaleźć kompilator, a wyodrębnienie tej równoległości jest trudne. Znajomość reguł językowych daje więcej możliwości niż w przypadku ograniczenia przez coś już zaplanowanego. Moim (przyznanym niewiarygodnym i od kogoś, kto śledził to z daleka) wspomnieniem jest to, że HP (*) i Intel nie osiągnęli na froncie kompilatora to ekstrakcja równoległości na poziomie języka, a nie niski poziom, który byłby obecny w bajcie kod.
Być może nie doceniasz kosztu, przy którym obecny procesor osiąga swoją wydajność. OOO jest bardziej skuteczna niż inne możliwości, ale z pewnością nie jest wydajna. Firma EPIC chciała wykorzystać budżet obszarowy wykorzystywany przez wdrożenie OOO do zapewnienia większej liczby surowych obliczeń, mając nadzieję, że kompilatory będą w stanie z niego skorzystać. Jak napisano powyżej, nie tylko nadal nie jesteśmy w stanie - jako AFAIK, nawet teoretycznie - pisać kompilatorów, które mają tę zdolność, ale Itanium dostał wystarczająco dużo innych trudnych do wdrożenia funkcji, że było późno, a jego surowa moc nie była nawet konkurencyjny (z wyjątkiem być może na niektórych niszowych rynkach z dużą ilością obliczeń FP) z innym wysokiej klasy procesorem, gdy wyszedł z fab.
(*) Wydajesz się również nie doceniać roli HP w EPIC.
źródło
Kilka spraw.
Na przykład IPF był w porządku. Oznaczało to, że nie możesz polegać na zmianie kolejności w celu uratowania Cię w przypadku braku pamięci podręcznej lub innego długotrwałego zdarzenia. W rezultacie musiałeś polegać na funkcjach spekulacyjnych - mianowicie obciążeniach spekulacyjnych (obciążeniach, które mogły ulec awarii - przydatne, jeśli nie wiedziałeś, czy potrzebujesz wyniku obciążenia) i obciążeniach zaawansowanych (obciążeniach, które mogą być uruchom ponownie, używając kodu odzyskiwania, jeśli wystąpiło zagrożenie.) Poprawne wykonanie tego zadania było trudne, szczególnie zaawansowane obciążenia! Były też wskazówki dotyczące pobierania z gałęzi i pamięci podręcznej, które naprawdę mogły być inteligentnie wykorzystane przez programistę asemblera lub przy pomocy optymalizacji kierowanej profilem, zazwyczaj nie w przypadku tradycyjnego kompilatora.
Inne maszyny w tym czasie - mianowicie UltraSPARC - były w porządku, ale IPF miał również inne względy. Jednym z nich było kodowanie przestrzeni. Instrukcje Itanium z natury nie były szczególnie gęste - 128-bitowy pakiet zawierał trzy operacje i 5-bitowe pole szablonu, które opisywały operacje w pakiecie i czy wszystkie mogły być wydawane razem. Dzięki temu uzyskano efektywny rozmiar operacji 42,6 bitów - w porównaniu z 32 bitami dla większości operacji komercyjnych RISC w tym czasie. (Było to wcześniej niż Thumb2 i wsp. - RISC nadal oznaczało sztywność o stałej długości.) Co gorsza, nie zawsze miałeś wystarczająco ILP, aby dopasować się do szablonu, którego używałeś - więc musisz wypełnić podkładkę NOP, aby wypełnić szablon lub pakiet. To, w połączeniu z istniejącą względną niską gęstością, oznaczało, że uzyskanie przyzwoitego współczynnika trafień w pamięci podręcznej i) było bardzo ważne,
Chociaż zawsze uważałem, że argument „kompilatora był jedynym i jedynym problemem” był przesadzony - istniały uzasadnione problemy mikroarchitektoniczne, które naprawdę nie sprzyjały kodowi ogólnego przeznaczenia - generowanie kodu dla porównania nie było szczególnie zabawne do węższych, o taktowanych maszynach OoO dnia. Gdy można było naprawdę poprawnie go wypełnić, co często wymagało PGO lub ręcznego kodowania, działało świetnie - ale przez większość czasu wydajność kompilatorów była po prostu mało inspirująca. IPF nie ułatwił generowania świetnego kodu, i był niewybaczalny, gdy kod nie był świetny.
źródło
To, co opisujesz, jest trochę tym, co Transmeta próbowała zrobić ze swoim oprogramowaniem do przekształcania kodu (które dynamicznie tłumaczyło „kod bajtowy” x86 na wewnętrzny kod maszynowy Transmeta).
Co do tego, dlaczego Intel nie stworzył wystarczająco dobrego kompilatora dla IA64 ... Myślę, że nie mieli wystarczającej wiedzy na temat kompilatora (nawet jeśli oczywiście mieli kilku bardzo dobrych ekspertów od kompilatorów, ale prawdopodobnie nie dość zrobić masę krytyczną). Myślę, że ich zarząd nie docenił wysiłków potrzebnych do stworzenia kompilatora.
AFAIK, Intel EPIC nie powiodło się, ponieważ kompilacja dla EPIC jest naprawdę trudna, a także dlatego, że gdy technologia kompilatora powoli i stopniowo ulepszana, inni konkurenci również mogli ulepszyć swój kompilator (np. Dla AMD64), dzieląc się wiedzą na temat kompilatora.
BTW, żałowałem, że AMD64 nie byłby jakimś zestawem instrukcji RISCy. Mógł to być POWERPC64 (ale prawdopodobnie nie z powodu problemów patentowych, z powodu wymagań Microsoft w tym czasie itp.). Architektura zestawu instrukcji x86-64 nie jest tak naprawdę „bardzo dobrą” architektem piszącym kompilatory (ale jest w jakiś sposób „wystarczająco dobra”).
Również architektura IA64 ma pewne silne ograniczenia, np. 3 instrukcje / słowo były dobre, o ile procesor miał 3 jednostki funkcjonalne do ich przetworzenia, ale kiedy Intel poszedł do nowszych układów IA64, dodał więcej jednostek funkcjonalnych, a instrukcja- poziom równoległości był ponownie trudny do osiągnięcia.
Być może RISC-V (który jest ISA typu open source) stopniowo odniesie sukces, aby uczynić go konkurencyjnym wobec innych procesorów.
źródło
Jak zauważył Robert Munn - to brak kompatybilności wstecznej zabił Itanium (i wiele innych „nowych” technologii).
Pisanie nowego kompilatora może być trudne, potrzebujesz tylko kilku z nich. Kompilator prądu zmiennego, który wytwarza zoptymalizowany kod, jest koniecznością - w przeciwnym razie nie będziesz mieć systemu operacyjnego. Potrzebujesz kompilatora C ++, Java i biorąc pod uwagę, że główną bazą użytkowników będzie Windows, jakiś Visual Basic. To nie był tak naprawdę problem. Dostępny był przyzwoity system operacyjny (NT) i dobry kompilator C.
To, co wydawałoby się trywialnym wysiłkiem dla firmy oferującej oprogramowanie - ponowne skompilowanie i ponowne przetestowanie bazy kodu C (a w tym czasie większość byłaby napisana w czystym C!), Nie było takie proste; konwersja dużego zestawu programów C, które przyjęły 32-bitową liczbę całkowitą i założyły 32-bitowe adresowanie do natywnej architektury 64-bitowej, było pełne pułapek. Gdyby IA64 stał się dominującym układem (a nawet popularnym!), Większość firm programistycznych ugryzłaby się w kulę i podjęła wysiłek.
Tak szybki układ z rozsądnym systemem operacyjnym, ale bardzo ograniczonym zestawem dostępnego oprogramowania, dlatego niewiele osób go kupiło, dlatego niewiele firm programowych zapewniało dla niego produkty.
źródło
Tym, co zabiło Itanium, były opóźnienia w wysyłce, które otworzyły drzwi AMD64 do wejścia, zanim dostawcy oprogramowania zdecydowali się na migrację do IA64 dla aplikacji 64-bitowych.
Pozostawienie optymalizacji kompilatorowi było dobrym pomysłem. Można wykonać wiele rzeczy statycznych, które w innym przypadku są nieefektywne sprzętowo. Kompilatory stały się w tym całkiem niezłe, szczególnie gdy korzystałem z profilowania PGO (pracowałem w HP, a kompilator HP miał tendencję do osiągania lepszych wyników niż Intel). PGO było trudną sprzedażą, ale jest to trudny proces dla kodu produkcyjnego.
IPF miał być kompatybilny wstecz, ale kiedy uruchomiono AMD64, stał się dyskusyjny, bitwa została przegrana i wierzę, że sprzęt X86 w procesorze został po prostu rozebrany, aby przekierować go jako procesor serwera. Itanium jako architektura nie była zła, 3 instrukcje na słowo nie stanowiły problemu. Problem polegał na tym, że implementacja hiperwątkowości polegała na tym, że zamiana stosów podczas operacji we / wy pamięci była zbyt wolna (aby opróżnić i ponownie załadować potok) aż do Montecito itp., Co uniemożliwiło mu konkurowanie z nieobsługiwanymi procesorami PowerPC. Kompilatory musiały załatać późne w celu wykrycia wad implementacji procesora, a część przewagi wydajności została utracona z powodu trudnych do przewidzenia błędów.
Architektura pozwoliła Itaniumowi być stosunkowo prostym, zapewniając jednocześnie kompilatorowi narzędzia pozwalające uzyskać z niego wydajność. Gdyby platforma żyła, procesory stałyby się bardziej złożone i ostatecznie zostałyby podzielone na wątki, zepsute itp., Takie jak x86. Jednak pierwsze geny skoncentrowały tranzystor na innych schematach wydajności, ponieważ kompilator poradził sobie z wieloma trudnymi sprawami.
Platforma IPF postawiła na kompilator i narzędzia, i była to pierwsza architektura, która ujawniła niezwykle kompletny i potężny projekt jednostki monitorowania wydajności (PMU), która została później przeniesiona z powrotem na Intel x86. Tak potężni twórcy narzędzi wciąż nie wykorzystują go do pełnej zdolności do profilowania kodu.
Jeśli spojrzysz na sukcesy ISA, często to nie strona techniczna rzuca kostką. To miejsce w czasie i siłach rynkowych. Spójrz na SGI Mips, DEC Alpha ... Itanium był właśnie wspierany przez przegranych, serwery SGI i HP, firmy z zarządami, które stosowały strategiczne błędy biznesowe. Microsoft nigdy nie był w pełni zaangażowany i nie zaakceptował AMD64, aby nie być zapakowanym tylko z Intelem jako odtwarzaczem, a Intel nie grał dobrze z AMD, aby dać im sposób na życie w ekosystemie, ponieważ zamierzali zgasić AMD.
Jeśli spojrzysz na to, gdzie jesteśmy dzisiaj, skomplikowany sprzęt X86 doprowadził go do ślepej ewolucji. Utknęliśmy na 3 + GHz, a zrzuty rdzeni są niewystarczające. Prostsza konstrukcja Itanium zepchnąłaby więcej rzeczy na kompilator (miejsce na wzrost), pozwalając budować cieńsze, szybsze rurociągi. Przy tej samej generacji i wspaniałej technologii działałby szybciej i byłby zamknięty tak samo, ale nieco wyżej, z innymi drzwiami, które mogłyby się otworzyć, by popchnąć prawo Moore'a.
Cóż, przynajmniej powyższe są moje przekonania :)
źródło
Pamięć staje się niejasna ... Itanium miał kilka świetnych pomysłów, które wymagałyby świetnej obsługi kompilatora. Problem polegał na tym, że nie była to jedna funkcja, było ich wiele. Każdy z nich nie był niczym wielkim, wszyscy razem byli.
Na przykład istniała funkcja zapętlania, w której jedna iteracja pętli działałaby na rejestrach z różnych iteracji. x86 radzi sobie z tym samym problemem dzięki ogromnym możliwościom braku zamówienia.
W tym czasie Java i JVM były modne. IBM powiedział, że dzięki PowerPC można szybko skompilować kod bajtowy, a procesor przyspieszy. Nie na Itanium.
źródło