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ę:
Odpowiedzi ładowania z hierarchii pamięci, która obejmuje pamięci podręczne procesora i pamięć DRAM, nie mają deterministycznego opóźnienia.
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:
- Oblicz adres, a następnie
- Przeczytaj wartość, a następnie
- Użyj go w niektórych obliczeniach
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ć.
- Powiedzmy, że aby skutecznie ukryć stragany, musimy wypełnić 100 instrukcji, które nie zależą od pamięci (więc nie będą cierpieć z powodu dodatkowych opóźnień).
- Teraz, jako programista, załaduj dowolne oprogramowanie do dezasemblera. Wybierz losową funkcję do analizy.
- Czy potrafisz zidentyfikować sekwencję 100 instrukcji (*), które są wyłącznie wolne od dostępu do pamięci?
(*) 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:
- Brak bezpośredniego dostępu do pamięci;
- Każdy dostęp do pamięci (odczyt lub zapis) musi być zaplanowany przez transfer DMA;
- Każda instrukcja ma takie samo opóźnienie wykonania;
- Realizacja zamówienia;
- Szerokie / wektoryzowane jednostki wykonawcze;
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.