W jaki sposób procesor może dostarczyć więcej niż jedną instrukcję na cykl?

41

Instrukcja Wikipedii na sekundę mówi, że i7 3630QM zapewnia ~ 110 000 MIPS przy częstotliwości 3,2 GHz; byłoby to (instrukcje 110 / 3.2) / 4 rdzenie = ~ 8,6 instrukcji na cykl na rdzeń ?! Jak pojedynczy rdzeń może dostarczyć więcej niż jedną instrukcję na cykl?

W moim rozumieniu potok powinien być w stanie dostarczyć tylko jeden wynik na zegar.

Oto moje myśli:

  • Częstotliwość wewnętrzna jest w rzeczywistości wyższa niż 3,2 GHz
  • Niektóre części procesora są asynchroniczne w sposób, którego tak skromny człowiek jak ja nie może zrozumieć
  • Istnieje wiele współbieżnych potoków na rdzeń
  • Potok może dostarczyć więcej niż wynik na zegar, instrukcja może pominąć etapy potoku i istnieje wiele preselektorów, aby nadążyć
  • Coś mi brakuje
Pracuj mniej
źródło
1
Dostarcza 110 000 Dhrystone MIPS, więc DMIPS, a nie MIPS, jest czymś, co widzę bezpośrednio - może to może coś zmienić? Zobacz en.wikipedia.org/wiki/Dhrystone

Odpowiedzi:

44

Po pierwsze, jak zauważają komentarze Keelana i odpowiedź Turbo J , pomiar wynosił 113 093 Dhrystone MIPS, a nie rodzimy MIPS.

Mikroarchitektura Ivy Bridge w i7 3630QM może zatwierdzić tylko 4 stopione µops na cykl, choć może rozpocząć wykonywanie 6 µops na cykl. (Liczba stopionych mikroprocesorów w śladzie kodu jest w przybliżeniu równa liczbie instrukcji; niektóre złożone instrukcje są dekodowane w wiele mikroprocesorów, które nie są stopione, a niektóre pary instrukcji mogą zostać połączone w pojedynczy mikroprocesor, np. Natychmiastowe porównanie a następnie skok warunkowy.)

Dwie twoje spekulacje na temat tego, w jaki sposób można wykonać wiele instrukcji w jednym cyklu, są dość aktualne i zostały wykorzystane w rzeczywistych procesorach. Twoja pierwsza spekulacja, że ​​używany jest szybszy zegar wewnętrzny, została wykorzystana w oryginalnych ALU „ognistej kuli” Pentium 4. Te ALU były taktowane dwukrotnie większą częstotliwością niż reszta rdzenia, która była już stosunkowo wysoka.

(Osiągnięto to poprzez zastosowanie przesuniętej ALU, w której dolna połowa dodawania została wykonana w jednym cyklu, umożliwiając zależnej operacji wykorzystanie dolnej połowy wyniku w następnym cyklu. W przypadku operacji takich jak dodawanie, xor lub lewe przesunięcie które potrzebują tylko dolnej połowy argumentów, aby uzyskać pełną dolną połowę wyniku, takie przesunięcie - znane również jako potokowanie szerokości - pozwala na opóźnienie wyniku pojedynczego cyklu, a także przepustowość pojedynczego cyklu).

HyperSPARC wykorzystał nieco pokrewną technikę, kaskadowe ALU. HyperSPARC wprowadził wyniki z dwóch ALU do trzeciej ALU. Umożliwiło to wykonanie dwóch niezależnych i trzeciej zależnej operacji w jednym cyklu.

Twoja spekulacja, że ​​„istnieje wiele równoległych potoków na rdzeń” to inna technika, która została zastosowana. Ten typ konstrukcji jest nazywany superskalarnym i jest zdecydowanie najczęstszym sposobem na zwiększenie liczby operacji wykonywanych w jednym cyklu.

Warto również zwrócić uwagę na kilka innych szans i zakończeń wykonywania instrukcji. Niektóre operacje można wydajniej wykonywać poza zwykłymi jednostkami wykonawczymi. Technika eliminacji przenoszenia wykorzystuje wykorzystanie zmiany nazwy rejestru w procesorach poza kolejnością do wykonywania operacji przenoszenia podczas zmiany nazwy rejestru; ruch po prostu kopiuje numer rejestru fizycznego z jednej pozycji w tabeli zmiany nazwy (zwanej tabelą aliasów rejestru) do innej. To nie tylko skutecznie zwiększa szerokość wykonania, ale także usuwa zależność. Technikę tę stosowano wcześniej w x87 opartej na stosie, ale obecnie jest szeroko stosowana w wysokowydajnych procesorach x86 Intela. (Zastosowanie destrukcyjnych instrukcji z dwoma argumentami w x86 sprawia, że ​​eliminacja ruchu jest bardziej pomocna niż w typowym RISC.)

Techniką podobną do eliminacji ruchu jest obsługa instrukcji zerowania rejestru podczas zmiany nazwy. Podając nazwę rejestru, która podaje wartość zerową, instrukcja kasowania rejestru (np. Xor lub odejmij, przy czym oba operandy są tym samym rejestrem) może po prostu wstawić tę nazwę do tabeli zmiany nazwy (RAT).

Inna technika stosowana przez niektóre procesory x86 zmniejsza koszty operacji push i pop. Zwykle instrukcja wykorzystująca wskaźnik stosu musiałaby czekać pełny cykl na poprzednie wypychanie lub pop, aby zaktualizować wartość wskaźnika stosu. Uznając, że push i pop tylko dodają lub odejmują niewielką wartość wskaźnika stosu, można obliczyć wyniki wielu dodań / poddziałań równolegle. Głównym opóźnieniem dodawania jest propagacja przenoszenia, ale przy małych wartościach bardziej znaczące bity wartości podstawowej - w tym przypadku wskaźnika stosu - będą miały najwyżej jedno przeniesienie. Pozwala to zastosować optymalizację podobną do optymalizacji sumy „carry-select” w przypadku wielu dodatków o małych wartościach. Ponadto, ponieważ wskaźnik stosu jest zwykle aktualizowany tylko przez stałe,

Możliwe jest również scalenie instrukcji w jedną, bardziej złożoną operację. Podczas gdy odwrotny proces dzielenia instrukcji na wiele, prostsze operacje są starą techniką, łączenie instrukcji (które Intel określa jako fuzja makrooperacji) może umożliwić implementacji obsługę operacji bardziej złożonych niż te ujawnione w zestawie instrukcji.

Od strony teoretycznej zaproponowano inne techniki. Małe stałe inne niż zero mogą być obsługiwane w RAT, a niektóre proste operacje, które wykorzystują lub niezawodnie wytwarzają tak małe wartości, mogą być obsługiwane wcześniej. („Inlining rejestru fizycznego”, Mikko H. Lipasti i in., 2004, zasugerowali użycie RAT jako sposobu zmniejszenia liczby rejestrów, ale pomysł można rozszerzyć, aby obsługiwał ładowanie małych natychmiastowych i prostych operacji na małych liczbach.)

W przypadku pamięci podręcznych śledzenia (które przechowują sekwencje instrukcji przy określonych założeniach przepływu sterowania) mogą istnieć możliwości scalenia operacji oddzielonych gałęziami i usunięcia operacji, które powodują niewykorzystane wyniki śledzenia. Buforowanie optymalizacji w pamięci podręcznej śledzenia może również zachęcać do przeprowadzania optymalizacji, takich jak łączenie instrukcji, co może nie być opłacalne, jeśli trzeba je wykonać przy każdym pobieraniu strumienia instrukcji.

Prognozowania wartości można użyć do zwiększenia liczby operacji, które można wykonać równolegle poprzez usunięcie zależności. Predyktor wartości oparty na krokach jest podobny do wspomnianej wcześniej optymalizacji pop / push wyspecjalizowanego silnika stosu. Może obliczać wiele dodatków głównie równolegle, usuwając serializację. Ogólna koncepcja przewidywania wartości polega na tym, że przy przewidywanej wartości operacje zależne mogą przebiegać bezzwłocznie. (Kierunek rozgałęzienia i przewidywanie celu jest w rzeczywistości bardzo ograniczoną formą przewidywania wartości, umożliwiającą pobranie następujących instrukcji, które zależą od „wartości” rozgałęzienia - wziętej lub nie - oraz adresu następnej instrukcji, innej wartości.)

Paul A. Clayton
źródło
niesamowite! Dziękuję za cenne informacje. Czy możesz zasugerować książkę, w której mogę przeczytać wszystkie te techniki architektoniczne?
workless
@workless Po wyjściu z podstaw wykonywania potoków i wykonywania superskalarnych zadań poza kolejnością (które byłyby omówione w większości podręczników architektury komputerowej) najlepszym źródłem informacji są prawdopodobnie opisy konkretnych mikroarchitektur procesorów (takich jak artykuł na temat Haswell w odpowiedzi gnasher729 ) i artykuły naukowe (konferencje ISCA i MICRO [ogólnie] mają ogólnie dobre artykuły; HPCA, PACT, ASPLOS i być może kilka innych również ma dobrą reputację). Andy Glew (być może najbardziej znany z pracy nad Pentium Pro) ...
Paul A. Clayton
1
... pracował na wiki CompArch, która przedstawiałaby bardziej zaawansowane koncepcje, ale postęp był powolny i najwyraźniej został zhakowany jakiś czas temu, więc teraz wyświetla tylko komunikat o błędzie ( semipublic.comp-arch.net/wiki ). Zamierza przywrócić wiki (oryginalny tekst został zachowany) przy użyciu innego oprogramowania wiki (miał pewne problemy z oprogramowaniem, którego używał i wykorzystuje to jako okazję do wprowadzenia ulepszeń), ale „To zajmie trochę czasu”.
Paul A. Clayton
Dobrym przykładem sukcesu architektury superskalarnej był HyperThreading Intela - przy tych wszystkich optymalizacjach inżynierowie Intela odkryli, że około 30% ALU było przez większość czasu nieużywane, ponieważ pamięć nie może przepłynąć wystarczająco szybko lub rurociąg nie może być wystarczająco skutecznie wypełniony. HyperThreading pozwala uzyskać dużo pracy za darmo w idealnym scenariuszu. Jest to o wiele mniej niż posiadanie osobnego nowego rdzenia, ale jest również znacznie tańsze (i można go również łączyć z wielordzeniowym).
Luaan
@ PaulA.Clayton - dwa zdjęcia tej strony znajdują się w serwisie Wayback. 20 grudnia 2013 r. I 14 lutego 2014 r . Nie wiem, czy te zdjęcia poprzedzają problemy ze stroną. Niestety, kiedy próbowałem odwiedzić te strony na Wayback, dostałem komunikat „ Bummer. Maszyna obsługująca ten plik jest wyłączona. Pracujemy nad tym. ”, Więc nie jestem pewien, co można zobaczyć na tych stronach .
Kevin Fegan
10

Pewna mroczna magia dzieje się w nowoczesnych procesorach, ale twoje myśli są zdecydowanie właściwe.

Kluczem do zrozumienia wydajności współczesnych procesorów jest uświadomienie sobie, że są one superskalarne . Z Wikipedii (moje podkreślenie):

Superskalarna architektura procesora realizuje formę równoległości zwanej równoległością na poziomie instrukcji w ramach jednego procesora. Pozwala to zatem na szybszą przepustowość procesora niż byłoby to możliwe przy danej częstotliwości taktowania.

Te nowoczesne procesory mają wiele jednostek wykonawczych na rdzeń, jak się domyślacie. Interesujące jest hiperwątkowanie , niektóre części potoku są zduplikowane, a niektóre nie.

Wykonanie poza kolejnością jest również interesujące, o którym można przeczytać, ale nie odpowiada bezpośrednio na twoje pytanie. Zmniejsza to jednak liczbę „zmarnowanych” cykli procesora.

Na efektywność ma również wpływ wiele innych rzeczy, które mogą powodować blokadę wewnątrz procesora, w tym (ale zdecydowanie nie tylko):

  • Wyniki poprzednich instrukcji nie są dostępne.
  • Pamięć podręczna nie trafia.
  • Rozgałęzienie kodu, które unieważniłoby już pobrane instrukcje (przeczytaj o przewidywaniu gałęzi tutaj i tutaj ).

Nowoczesne kompilatory próbują pomóc w wielu z powyższych elementów, a następnie procesor przejmuje kontrolę. Dla dobrego przykładu zobacz to pytanie w innym miejscu na Stackexchange, który podkreśla istotną różnicę między dwiema instrukcjami, które mogą zrobić to samo (w niektórych okolicznościach). Jednak na niektórych procesorach jeden może być „szybszy” niż drugi ze względu na używaną jednostkę wykonawczą.

Aby zapoznać się z czytelnym dla człowieka objaśnieniem współczesnego potoku procesora, zobacz Podróż przez potok procesora . Aby uzyskać nieco bardziej techniczne wyjaśnienie, zobacz dokument Microarchitecture Agner Fog .

David
źródło
dziękuję za wyjaśnienie i bardzo interesujące linki. Jak zauważam, Cell wygląda bardzo interesująco, nie mogę się doczekać, aby dowiedzieć się więcej o architekturach procesorów ^ _ ^. „” X86 używa „superpipeline”, jak opisano powyżej. Rodzina Cell stosuje podejście „synergistyczne” obejmujące dziewięć mini-procesorów. Prawdą jest, że każda mini-cpu następująco rurociągu głównie na zamówienie, mini-Procesory mają wiele równoległych superskalarnych rurociągi zamiast pojedynczego rurociągu „””.
workless
3

Jak myślisz, co się stało: wszyscy inżynierowie z Intela, AMD i IBM przeczytali, że potok może dostarczyć tylko jeden wynik na cykl, i powiedzieli „no cóż, więc to nie może przyspieszyć tych procesorów”. Czy też przeczytali to i powiedzieli: „Nie można dostarczyć więcej niż jednego wyniku na cykl? Zobaczymy o tym!”.

Aby na przykład zapoznać się z architekturą Haswell, możesz skorzystać z tego linku http://www.realworldtech.com/haswell-cpu/ lub po prostu przejść na stronę Intela, gdzie znajdziesz trochę dokumentacji.

Każdy rdzeń procesora Haswell ma ogromną liczbę jednostek wykonawczych, które mogą wykonywać operacje niezależnie od siebie, dzięki czemu wiele operacji może być wykonywanych równolegle. Następnie procesor Haswell ma kilka jednostek wykonawczych, które obsługują operacje wektorowe o wielkości do 256 bitów. Operacja wektorowa może na przykład wykonywać cztery operacje zmiennoprzecinkowe podwójnej precyzji lub osiem operacji zmiennoprzecinkowych pojedynczej precyzji w jednej operacji wektorowej. I na koniec procesor Haswella obsługuje „łączone wielokrotne dodawanie”, co oznacza, że ​​obliczenie razy b plus c jest tylko pojedynczą operacją.

Teoretyczne maksimum, ponieważ Haswell ma dwie jednostki zdolne do stopionego dodawania wielokrotnego dodawania, to dwie stopione operacje wielokrotnego dodawania na cykl, każda operacja wykonuje osiem pojedynczych precyzji mnożenia i dodawania lub 32 pojedyncze precyzyjne operacje zmiennoprzecinkowe.

Procesor 3630 nie znajduje się w najnowszym cenniku Intela, ale istnieją modele takie jak 3740QM z czterema rdzeniami. Zamiast 32 możesz uzyskać 128 operacji zmiennoprzecinkowych na cykl zegara. To teoretyczne maksimum. Osiągnięcie połowy tego w prawdziwym życiu jest wyzwaniem, ale nie jest niemożliwe do wykonania odpowiednich zadań. Istnieją inne procesory dostępne z maksymalnie 15 rdzeniami (w cenach, które nie zapłacą nawet najbardziej fanatyczni fanatycy gier).

Masz więc kombinację kilku mnożników:

  1. Wiele rdzeni na procesor.
  2. (Hyperthreading, nie wspomniany wcześniej, pozwala zbliżyć się do teoretycznych limitów)
  3. Połączona operacja wielokrotnego dodawania wykonuje dwie operacje arytmetyczne, licząc tylko jako jedną.
  4. Wektory 256-bitowe wykonują 8 operacji, licząc tylko jedną.
  5. Dwie jednostki wykonujące wektor, zdolne do obsługi dodawania i łączenia.

8,6 operacji na cykl nie jest zbyt trudne do osiągnięcia. Nawet 8,6 operacji na cykl na rdzeń nie jest zbyt trudne.

gnasher729
źródło
Zastanawiam się, czy byłoby praktyczne lub korzystne zaprojektowanie procesora z niektórymi rdzeniami, które działały na x86, a niektóre działały z zestawem instrukcji zoptymalizowanym pod kątem zachowania superskalarnego. Wiem, że Intel i AMD robią niesamowite rzeczy, aby obejść ograniczenia w zestawie instrukcji x86, ale w niektórych przypadkach pomyślałem, że znajomość niektórych rzeczy, których obecny zestaw instrukcji nie może wyrazić, byłby pomocny. Na przykład, odrębne wersje ADDinstrukcji oparte na tym, czy przepełnienie powinno pozostać niezmienione, czy też należy je ustawić, gdy nastąpi przepełnienie (i pozostawić ustawione, jeśli tak nie jest).
supercat
1
Smutno mi, że w dzisiejszych czasach wiele języków domyślnie nie sprawdza przepełnienia. Wiem, że Java jest bardzo ograniczona wymaganiami semantycznymi, ale w językach takich jak C #, które obejmują zarówno pułapki, jak i pułapki, operatory arytmetyczne, jedynym dobrym powodem, dla którego nie widzę pułapki przepełnienia, jest to, że potrzebujemy zachowania zawijania. Obecnie kontrola przepełnienia może nałożyć znaczną karę prędkości, ale jeśli język maszynowy
zostałby
... osiąga określone punkty krytyczne, powinno być możliwe zredukowanie napowietrzenia przechwytywania do prawie zera. Jeśli kod wykonuje obliczenia, a następnie przechowuje wartość w lokalizacji, która zostanie porzucona w przypadku przepełnienia pierwszego obliczenia, nie powinno być potrzeby opóźniania zapisu, dopóki procesor nie dowie się, czy pierwsze obliczenie się powiedzie, ale procesor obecnie nie ma możliwości o tym wiedzieć. Jeśli kod może po prostu wykonać wszystkie operacje, które mogą być bezpiecznie wykonywane czy nie nastąpiło przepełnienie, a następnie sprawdzić, czy jakiekolwiek niewłaściwe przepełnienia wystąpił na żadnym z nich ...
Supercat
... wydaje się, że powinno to pomóc zmniejszyć zależności wykonywania.
supercat
2

Benchmark Drystone pochodzi z 1984 roku, a odpowiadająca mu nominalna maszyna 1 MIPS VAX nie jest bardzo wydajna pod względem nowoczesnym. Nawet Cortex M3 zapewnia 1,25 DMPIS / MHz.

Procesory achitecture Intel Core mogą rzeczywiście uruchamiać wiele instrukcji równolegle w jednym rdzeniu, ponieważ obecnych jest wiele jednostek obliczeniowych.

Turbo J
źródło
1

Nauczyłem się bardzo dużo od Jona „Hannibala” Stssa z Ars Technica doskonałych i obszernych artykułów na temat architektury mikroprocesorów. Artykuły są nieco przestarzałe (wydaje się, że pochodzą z około 2004 roku), ale nadal są bardzo aktualne.

Niektóre linki do następnej części artykułu są zepsute, jednak wydaje się, że możesz je naprawić samodzielnie, ostrożnie porównując adres URL pierwszej części i uszkodzony adres URL następnej strony (np. Dodając m-gdzieś w adresie URL).

(tak, to jest chwalebna odpowiedź tylko za pośrednictwem linku, przepraszam; artykuły są zbyt piękne, aby o nich nie wspomnieć)

marcelm
źródło