Czytałem to bardzo interesujące pytanie na temat przepełnienia stosu:
Jeden z komentarzy powiedział:
„Nic nie warte jest tego, że w Haswell przepustowość multiplikacji FP jest dwukrotnie większa niż w przypadku dodawania FP. Jest tak, ponieważ oba porty 0 i 1 mogą być używane do mnożenia, ale tylko port 1 może być używany do dodawania. To powiedziawszy, można oszukiwać za pomocą fuzji -multiply dodaje, ponieważ oba porty mogą to zrobić. ”
Dlaczego dopuszczają dwa razy więcej jednoczesnych zwielokrotnień w porównaniu do dodawania?
cpu
computer-architecture
alu
floating-point
intel
użytkownik1271772
źródło
źródło
Odpowiedzi:
Prawdopodobnie odpowiada to na pytanie, jeśli nie na ciało:
Dodawanie zmiennoprzecinkowe wymaga wyrównania dwóch mantys przed ich dodaniem (w zależności od różnicy między dwoma wykładnikami), potencjalnie wymagając dużej zmiennej wartości przesunięcia przed sumatorem. Następnie może być potrzebna renormalizacja wyniku dodawania mantysy, potencjalnie wymagająca innej dużej zmiennej wartości przesunięcia, aby poprawnie sformatować wynik zmiennoprzecinkowy. Dwa manetki beczki mantysy potencjalnie wymagają zatem większych opóźnień bramki, większych opóźnień drutu lub dodatkowych cykli, które przekraczają opóźnienie dobrze zwartego przedniego końca multiplikatora przenoszenia-zapisywania-sumowania-drzewa.
Dodano dla OP: Należy pamiętać, że dodanie długości 2 milimetrów i 2 kilometrów nie jest równe 4 żadnej jednostce. Wynika to z potrzeby konwersji jednego lub drugiego pomiaru na tę samą skalę lub reprezentację jednostki przed dodaniem. Ta konwersja wymaga zasadniczo pomnożenia przez pewną potęgę 10. To samo zwykle musi się zdarzyć podczas dodawania liczb zmiennoprzecinkowych, ponieważ liczby zmiennoprzecinkowe są formą liczb całkowitych o zmiennej skali (np. Istnieje współczynnik jednostki lub skali, wykładnik, związany z każdy numer). Może więc być konieczne skalowanie jednej z liczb o potęgę 2 przed dodaniem surowych bitów mantysy, aby obie reprezentowały te same jednostki lub skalę. To skalowanie jest zasadniczo prostą formą mnożenia przez potęgę 2. Zatem dodawanie zmiennoprzecinkowe wymaga zwielokrotnienia(która jest potęgą 2, można to zrobić za pomocą zmiennego przesunięcia bitów lub dźwigni cylindra, co może wymagać stosunkowo długich drutów w stosunku do rozmiarów tranzystorów, które mogą być względnie wolne w głębokich obwodach submikronowych do litografii). Jeśli dwie liczby w większości się anulują (ponieważ jedna jest prawie ujemna względem drugiej), może zaistnieć potrzeba przeskalowania wyniku dodania, a także odpowiedniego sformatowania wyniku. Tak więc dodawanie może być powolne, jeśli ponadto wymaga 2 mnożenia (przed i po) kroków otaczających binarne dodawanie surowej stałej (skończonej) liczby bitów mantysy reprezentujących równoważne jednostki lub skalę, ze względu na charakter formatu liczb (zmiennoprzecinkowy IEEE ).
Dodano # 2: Ponadto wiele benchmarków waży FMACS (wielokrotnie się akumuluje) więcej niż gołe sumy. W skondensowanym MAC wyrównanie (przesunięcie) dodatku można często wykonać równolegle z mnożeniem, a dodatek mantysy można często włączyć do drzewa CSA przed ostateczną propagacją przenoszenia.
źródło
W multiplikacji FP przetwarzanie wykładnicze okazuje się prostym dodawaniem (z tego samego powodu, dla którego mnożenie w domenie dziennika jest jedynie dodawaniem). Mam nadzieję, że natknąłeś się na logarytmy.
Zastanówmy się teraz, jak trudno jest dodać dwie liczby w postaci logarytmicznej ...
Punkt zmiennoprzecinkowy zamieszkuje szary obszar między domenami liniową i logarytmiczną, z aspektami obu. Każdy numer FP zawiera mantysę (która jest liniowa) i wykładnik (logarytmiczny). Aby określić znaczenie każdego bitu w mantysie, musisz najpierw spojrzeć na wykładnik potęgi (który jest tylko współczynnikiem skali).
Ponadto FP, przetwarzanie wykładnika w ogólnym przypadku wymaga dwukrotnego przesunięcia mantysy, przy czym każde przesunięcie baryłki jest w rzeczywistości specjalnym przypadkiem nieco uproszczonego zwielokrotnienia.
(Pierwsze przesunięcie wyrównuje oba wejścia do tej samej mocy 2, dzięki czemu bit mantysy ma taki sam ciężar binarny w każdym operandzie.
Wystarczy ułamek dziesiętny (choć oczywiście używany jest plik binarny) ...
Drugi przeskalowuje wyjście ...
Paradoksalnie więc dodanie FP wiąże się z czymś bardzo podobnym do dwóch multiplikacji, które muszą być wykonane sekwencyjnie, z dodatkiem mantysy między nimi. W tym świetle zgłoszona wydajność nie jest tak zaskakująca.
źródło
TL: DR : ponieważ Intel uważał, że opóźnienie dodawania SSE / AVX FP jest ważniejsze niż przepustowość, postanowili nie uruchamiać go na urządzeniach FMA w Haswell / Broadwell.
Haswell uruchamia (SIMD) FP mnożąc się na tych samych jednostkach wykonawczych co FMA ( Fused Multiply-Add ), z których ma dwa, ponieważ niektóre intensywnie wykorzystujące FP kody mogą używać głównie FMA do wykonania 2 FLOP na instrukcję.
mulps
Tyle samo opóźnień 5 cykli, co FMA, i jak we wcześniejszych procesorach (Sandybridge / IvyBridge). Haswell chciał 2 jednostek FMA i nie ma żadnej wady pozwalającej na mnożenie na obu, ponieważ mają one takie samo opóźnienie jak dedykowana jednostka mnożąca we wcześniejszych procesorach.Ale utrzymuje dedykowaną jednostkę dodającą SIMD FP z wcześniejszych procesorów, aby nadal działać
addps
/addpd
z 3 opóźnieniami cyklu. Czytałem, że możliwym powodem może być ten kod, który dodaje wiele FP, ma tendencję do wąskiego gardła pod względem opóźnienia, a nie przepustowości. Z pewnością dotyczy to naiwnej sumy tablicy z jednym akumulatorem (wektorowym), jak to często bywa z automatycznym wektoryzowaniem GCC. Ale nie wiem, czy Intel publicznie potwierdził, że takie było ich rozumowanie.Broadwell jest taki sam ( ale przyspieszył
mulps
/mulpd
opóźnienie do 3c, podczas gdy FMA pozostał na poziomie 5c). Być może udało im się skrócić jednostkę FMA i uzyskać wynik mnożenia przed dodaniem fałszywego dodatku0.0
, a może coś zupełnie innego i to jest zbyt uproszczone. BDW jest głównie kurczeniem się HSW, przy czym większość zmian jest niewielka.W Skylake wszystko FP (łącznie z dodawaniem) działa na jednostce FMA z opóźnieniem 4 cykli i przepustowością 0,5c, z wyjątkiem oczywiście div / sqrt i bitowych booleanów (np. Dla wartości bezwzględnej lub negacji). Intel najwyraźniej zdecydował, że nie warto dodawać krzemu do dodawania FP z mniejszymi opóźnieniami lub że niezrównoważona
addps
przepustowość jest problematyczna. A także standaryzacja opóźnień ułatwia unikanie konfliktów zapisu (gdy 2 wyniki są gotowe w tym samym cyklu) łatwiej uniknąć w harmonogramie UOP. tj. upraszcza porty planowania i / lub zakończenia.Tak, Intel zmienił to w kolejnej ważnej rewizji mikroarchitektury (Skylake). Zmniejszenie opóźnienia FMA o 1 cykl sprawiło, że korzyść z dedykowanej jednostki dodającej SIMD FP była znacznie mniejsza, dla przypadków, które były związane z opóźnieniem.
Skylake wykazuje również oznaki przygotowywania się Intela do AVX512, w którym rozszerzenie oddzielnego sumatora SIMD-FP do 512 bitów zajęłoby jeszcze więcej miejsca na kości. Skylake-X (z AVX512) podobno ma prawie identyczny rdzeń jak zwykły klient Skylake, z wyjątkiem większej pamięci podręcznej L2 i (w niektórych modelach) dodatkowej 512-bitowej jednostki FMA „przykręconej” do portu 5.
SKX zamyka ALU portu 1 karty SIMD, gdy 512-bitowe przestoje są w locie, ale potrzebuje sposobu na wykonanie
vaddps xmm/ymm/zmm
w dowolnym momencie. Sprawiło to, że posiadanie dedykowanej jednostki FP ADD na porcie 1 stanowi problem i stanowi osobną motywację do zmiany w stosunku do wydajności istniejącego kodu.Ciekawostka: wszystko od Skylake, KabyLake, Coffee Lake, a nawet Cascade Lake było mikroarchitektycznie identyczne jak Skylake, z wyjątkiem Cascade Lake dodającego nowe instrukcje AVX512. IPC nie zmieniło się inaczej. Nowsze procesory mają jednak lepsze iGPU. Ice Lake (mikroarchitektura Sunny Cove) po raz pierwszy od kilku lat po raz pierwszy zobaczyliśmy nową mikroarchitekturę (z wyjątkiem nigdy nieopublikowanego powszechnie Cannon Lake).
Argumenty oparte na złożoności jednostki FMUL w porównaniu z jednostką FADD są interesujące, ale w tym przypadku nie mają znaczenia . Jednostka FMA zawiera cały niezbędny sprzęt do zmiany biegów, aby wykonać dodawanie FP jako część FMA 1 .
Uwaga: Nie mam na myśli
fmul
instrukcji x87 , mam na myśli multiplikację ALU SSE / AVX SIMD / skalarną FP, która obsługuje 32-bitową pojedynczą precyzję /float
i 64-bitowądouble
precyzję (53-bitowe znaczenie i inaczej mantysa). np. instrukcje takie jakmulps
lubmulsd
. Rzeczywista 80-bitowa x87fmul
to wciąż tylko 1 / zegar na Haswell na porcie 0.Współczesne procesory mają więcej niż wystarczającą liczbę tranzystorów, aby rzucać się na problemy, kiedy jest to tego warte , i kiedy nie powoduje to problemów z opóźnieniem propagacji na odległość fizyczną. Zwłaszcza dla jednostek wykonawczych, które są aktywne tylko przez pewien czas. Zobacz https://en.wikipedia.org/wiki/Dark_silicon i ten dokument konferencyjny 2011: Dark Silicon and the End of Multicore Scaling. Dzięki temu procesory mają dużą przepustowość FPU i masywną liczbę całkowitą, ale nie obie jednocześnie (ponieważ te różne jednostki wykonawcze są na tych samych portach wysyłających, więc konkurują ze sobą). W wielu starannie dopracowanych kodach, które nie ograniczają przepustowości pamięci, czynnikiem ograniczającym nie są jednostki wykonawcze zaplecza, ale przepustowość instrukcji frontonu. ( szerokie rdzenie są bardzo drogie ). Zobacz także http://www.lighterra.com/papers/modernmicroprocessors/ .
Przed Haswell
Przed HSW procesory Intel, takie jak Nehalem i Sandybridge, miały SIMD FP zwielokrotnione na porcie 0, a SIMD FP dodane na porcie 1. Więc były osobne jednostki wykonawcze i przepustowość była zrównoważona. ( https://stackoverflow.com/questions/8389648/how-do-i-achieve-the-theoretical-maximum-of-4-flops-per-cycle
Haswell wprowadził obsługę procesorów FMA w procesorach Intela (kilka lat po tym, jak AMD wprowadził FMA4 w Bulldozerze, po tym, jak Intel sfałszował je , czekając tak późno, jak to możliwe, aby upublicznić, że zamierzają wdrożyć 3-operand FMA, a nie 4-operand non -destructive-destination FMA4). Ciekawostka: AMD Piledriver był nadal pierwszym procesorem x86 z FMA3, około rok przed Haswell w czerwcu 2013 r.
Wymagało to poważnego zhakowania elementów wewnętrznych, aby nawet obsługiwać pojedynczy UOP z 3 wejściami. Ale w każdym razie Intel wszedł all-in i wykorzystał stale kurczące się tranzystory, aby zainstalować dwie 256-bitowe jednostki SIMD FMA, dzięki czemu Haswell (i jego następcy) są bestiami dla matematyki FP.
Cel wydajnościowy, jaki Intel mógł mieć na myśli, to gęsty matmuł BLAS i iloczyn wektorowy. Oba mogą w większości korzystać z FMA i nie muszą po prostu dodawać.
Jak wspomniałem wcześniej, niektóre obciążenia, które w większości lub po prostu dodają FP, są wąskie z powodu opóźnień w dodawaniu (głównie) nie przepustowości.
Przypis 1 : Z mnożnikiem
1.0
FMA można dosłownie wykorzystać do dodania, ale z gorszym opóźnieniem niżaddps
instrukcja. Jest to potencjalnie przydatne w przypadku obciążeń, takich jak sumowanie tablicy, która jest gorąca w pamięci podręcznej L1d, gdzie FP dodaje przepustowość ma większe znaczenie niż opóźnienie. Pomaga to tylko wtedy, gdy używasz wielu akumulatorów wektorowych do ukrycia opóźnienia i utrzymujesz 10 operacji FMA w locie w jednostkach wykonawczych FP (opóźnienie 5c / przepustowość 0,5c = 10 opóźnień operacji * iloczyn przepustowości). Musisz to zrobić, gdy używasz FMA również w przypadku produktu z kropkami wektorowymi .Zobacz, jak David Kanter napisał o mikroarchitekturze Sandybridge, która zawiera schemat blokowy, w których krajach UE znajduje się port dla NHM, SnB i AMD Bulldozer-family. (Zobacz także tabele instrukcji Agner Fog i przewodnik po mikroarchizmie optymalizacji asm, a także https://uops.info/, który zawiera również eksperymentalne testy uops, portów oraz opóźnienia / przepustowości niemal każdej instrukcji na wielu generacjach mikroarchitektur Intel).
Powiązane również: https://stackoverflow.com/questions/8389648/how-do-i-achieve-the-theoretical-maximum-of-4-flops-per-cycle
źródło
[cpu-architecture]
,[performance]
,[x86-64]
,[assembly]
, i[sse]
. Napisałem odpowiedź na temat kodu C ++, aby przetestować hipotezę Collatza szybciej niż zestaw odręczny - dlaczego? że wiele osób uważa za dobre. Także to dotyczy wykonywania potokowego OoO.Spojrzę na tę część:
„Dlaczego to na to pozwalają ” ...
TL; DR - ponieważ zaprojektowali to w ten sposób. To decyzja zarządcza. Pewnie, że są odpowiedzi mantysy i zmiennokształtnych, ale są to rzeczy, które należy do decyzji zarządczej.
Dlaczego tak to zaprojektowali? Odpowiedź jest taka, że specyfikacje zostały stworzone, aby osiągnąć określone cele. Cele te obejmują wydajność i koszty. Wydajność nie jest ukierunkowana na operacje, a raczej na test porównawczy, taki jak FLOPS lub FPS w Crysis.
Te testy porównawcze będą miały wiele funkcji, niektóre z nich mogą być przetwarzane jednocześnie.
Jeśli projektanci stwierdzą, że posiadanie dwóch funkcji widżetu A sprawia, że jest to znacznie szybsze, niż dwóch funkcji widżetu B, to pójdą z widżetem A. Wdrożenie dwóch A i dwóch B będzie kosztować więcej.
Patrząc wstecz, kiedy superskalarne i super-rurociągi (przed wielordzeniowym) po raz pierwszy stały się powszechne w komercyjnych układach scalonych, miały one na celu zwiększenie wydajności. Pentium ma dwie rury i żaden wektor się nie łączy. Haswell ma więcej rur, jednostek wektorowych, głębszą rurę, dedykowane funkcje i wiele innych. Dlaczego nie ma wszystkiego wszystkiego? Ponieważ tak to zaprojektowali.
źródło
Ten schemat od Intela może pomóc:
Wygląda na to, że dali każdej jednostce FMA (stopione dodawanie wielokrotne), a także mnożenie i pojedynczy sumator. Mogą lub nie mogą dzielić sprzęt pod spodem.
Pytanie, dlaczego dużo trudniej jest odpowiedzieć bez wewnętrznych uzasadnień projektowych, ale tekst w fioletowym polu daje nam wskazówkę dotyczącą „podwójnych szczytowych poziomów FLOP”: procesor będzie celował w zestaw testów porównawczych, pochodzących z rzeczywistych przypadków użycia. FMA jest w nich bardzo popularny, ponieważ jest podstawową jednostką mnożenia macierzy. Nagi dodatek jest mniej popularny.
Jak już wspomniano, można dodawać oba porty za pomocą instrukcji FMA, w której parametr zwielokrotnienia wynosi 1, obliczając (A x 1) + B. Będzie to nieco wolniejsze niż zwykłe dodawanie.
źródło
Rzućmy okiem na czasochłonne kroki:
Dodatek: Wyrównaj wykładniki (może to być operacja masowej zmiany). Jeden 53-bitowy sumator. Normalizacja (do 53 bitów).
Mnożenie: Jedna ogromna sieć sumatorów redukująca 53 x 53 produkty jednobitowe do sumy dwóch liczb 106-bitowych. Jeden 106-bitowy sumator. Normalizacja. Powiedziałbym, że zmniejszenie produktów bitowych do dwóch liczb może być wykonane tak szybko, jak ostatni sumator.
Jeśli możesz zrobić mnożenie zmiennej zmiennej czasowej, masz tę przewagę, że normalizacja przesunie się tylko o jeden bit przez większość czasu, i możesz bardzo szybko wykryć inne przypadki (zdenormalizowane dane wejściowe lub suma wykładników jest zbyt mała).
Ponadto bardzo często wymagane są kroki normalizacyjne (dodawanie liczb, które nie są równej wielkości, odejmowanie liczb, które są bliskie). Tak więc dla zwielokrotnienia możesz pozwolić sobie na szybką ścieżkę i wykonać ogromne uderzenie na wolną ścieżkę; na dodatek nie możesz.
PS. Czytanie komentarzy: Sensowne jest, że dodawanie liczb zdenormalizowanych nie powoduje kary: oznacza tylko, że spośród bitów przesuniętych w celu wyrównania wykładników wiele jest zerami. A wynik zdormalizowany oznacza, że przestajesz się przesuwać, aby usunąć zera wiodące, jeśli spowodowałoby to, że wykładnik byłby zbyt mały.
źródło
-ffast-math
zestawami FTZ / DAZ (odmiana koloru do zera), aby to zrobić, zamiast wziąć asysty FP.