Mateusz Brzostek | 30 marca 2017, 20:49

AMD Ryzen i optymalizacja oprogramowania

Kilka spostrzeżeń na temat instrukcji AVX/AVX2 i opymalizacji oprogramowania na przykładzie kodeka x265 oraz Ashes of the Singularity.

AVX i AVX2 w praktyce

Procesory Ryzen 7 mają dość nowoczesny zestaw instrukcji: obsługują praktycznie wszystkie stosowane w desktopowych procesorach rozszerzenia zestawu instrukcji, w tym AVX i AVX2. Te dwa ostatnie rozszerzenia pozwalają obrabiać 256-bitowe liczby (całkowite i naturalne) jedną instrukcją.

Teoretycznie 256-bitowe instrukcje pozwalają przetworzyć dwa razy więcej danych w takim samym czasie, niż 128-bitowe instrukcje SSE. W praktyce z pamięci trzeba pobrać więcej danych (i zapisać więcej wyników), długie instrukcje są bardziej skomplikowane do pobrania i zdekodowania, i tak dalej. Dwa razy większą wydajność w obliczeniach wektorowych da się uzyskać tylko wtedy, kiedy instrukcje AVX mają taką samą przepustowość i opóźnienie, jak ich odpowiedniki SSE. Przepustowość określa, ile średnio takich instrukcji daje wynik w jednym cyklu zegara, w optymalnych warunkach (strumień podobnych instrukcji, nawzajem niezależnych, bez oczekiwania na pamięć). Opóźnienie określa, ile cykli zegara średnio zajmuje wykonanie jakiejś instrukcji, od wysłania z kolejki mikrooperacji do otrzymania wyniku. Wydajność AVX byłaby dwa razy większa, gdyby odpowiednie instrukcje SSE miały dokładnie taką samą przepustowość i takie samo opóźnienie, a w praktyce tak nie jest – wszystko zależy od implementacji w konkretnym procesorze.

Ostatnie procesory Intela (Haswell i Skylake) mają 256-bitowe jednostki wykonawcze AVX/AVX2. Potrafią wykonać większość instrukcji z przepustowością jednej na cykl i opóźnieniem od jednego do 3 cykli. W wielu (ale nie wszystkich) przypadkach można osiągnąć znaczne przyspieszenie w stosunku do instrukcji 128-bitowych.

Tymczasem rdzenie Zen mają 128-bitowe jednostki arytmetyczne, zoptymalizowane głównie pod kątem instrukcji FMA (mnożenie dwóch liczb i dodawanie trzeciej do wyniku). Zen może wykonać jendocześnie dwa 128-bitowe mnożenia z dodawaniem, ale 256-bitowe instrukcje są wykonywane „na raty”, w dwóch cyklach, tak jak w poprzednich procesorach AMD. Teoretycznie maksymalna wydajność Zen w obliczeniach wektorowych jest dwa razy mniejsza, niż maksymalna wydajność Skylake lub Haswella. W praktyce wiele zależy od opóźnienia i przepustowości używanych instrukcji; poza tym żaden praktyczny program nie zbliża się nawet do teoretycznego maksimum przepustowości, ani nawet nie wykorzystuje AVX/AVX2 w zasadniczej części przeprowadzanych obliczeń.

x265 z AVX i AVX2

Jednym ze stosunkowo popularnych programów, które już wykorzystują AVX jest kodek x265. x265 to referencyjna implementacja formatu kodowania H.265 (HEVC), rozwijana przez firmę MulticoreWare dzięki sponsoringowi firm zainteresowanych wykorzystaniem tego formatu. x265 ma otwarty kod źródłowy; po skompilowaniu dostajemy enkoder działający z linii poleceń i wymagający dodatkowego oprogramowania. Kod x265 jest też używany w innych programach, na przykład w Handbrake.

Optymalizacja x265 dla nowoczesnych zestawów instrukcji polega na tym, że programiści określają, które funkcje kodera mają mieć specjalną wersję. Podczas kompilacji tworzone są osobne wersje tych funkcji, w których określone procedury zostają zamienione na ręcznie zoptymalizowane fragmenty asemblera, napisane ręcznie przez programistów MulticoreWare albo zapożyczone z YASM.

Chciałem sprawdzić, czy procesory Ryzen coś zyskują na implementacji AVX i AVX2 w x265. Teoretycznie w x265 można z linii komend wyłączyć różne optymalizacje bez rekompilowania, ale w Handbrake ta funkcja nie działa; skompilowałem więc Handbrake w dwóch wersjach. Pierwsza była zupełnie niezmieniona. W drugiej usunąłem z kodu wszystkie optymalizacje uruchamiane po wykryciu procesora z obsługą AVX i AVX (ale nie FMA ani SSE). Użyłem kompilatora GCC i standardowych ustawień rekomendowanych przez twórców Handbrake.

Jak się okazuje, własna wersja Handbrake jest nieco wolniejsza, niż pliki wykonywalne przygotowane przez twórców programu – zapewne twórcy Handbrake użyli innego kompilatora lub dyrektyw, niż zalecają publicznie, ale nie ma to większego znaczenia dla mojego eksperymentu.

x265_preset
Najpierw kodowałem film o rozdzielczości 1920×1080 i płynności 60 kl./sek. do formatu H.265, 1280×720, 30 kl./sek. Użyłem jednego z predefiniowanego ustawień jakości z kategorii MKV, w których domyślnie jest włączony filtr decomb. Mieszko zasugerował, że filtry są dość wymagające obliczeniowo, więc drugi raz sprawdziłem to samo z ręcznie wyłączonymi wszystkimi filtrami:

x265_nofilter

Oczywiście to za mało na porządny eksperyment; bez zrobienia wielu powtórzeń i wyciągnięcia średniej nie mam na przykład pewności, czy moja kompilacja bez AVX jest zawsze szybsza lub wolniejsza od wersji bez AVX na procesorach Ryzen, czy to tylko efekt rozrzutu w niepowtarzalnym teście. Za to mogę być pewien, że o ile na Ryzenach oficjalna kompilacja jest szybsza od mojej własnej, to różnice nie są zasadnicze. Natomiast na Kaby Lake moja własna kompilacja jest zauważalnie wolniejsza od oficjalnej, a wersja bez AVX/AVX2 potrafi być o 1/4 wolniejsza! To sugeruje, że jakiekolwiek optymalizacje AVX/AVX2 w kodzie x265 nie są w ogóle szybsze od wersji SSE na procesorach Ryzen.

x265 to przykład programu, w którym poświęcono już bardzo dużą uwagę optymalizacji kodu z wykorzystaniem instrukcji wektorowych. Nasuwają się dwa możliwe wyjaśnienia: albo x265 potrzebuje procedur ręcznie zoptymalizowanych specjalnie dla Zen, albo bardzo dobrze zoptymalizowany kod wektorowy z SSE i FMA wykorzystuje już całą przepustowość obliczeniową rdzenia, i zamiana na instrucje AVX nie powiększy już wydajności.

Przy okazji te wyniki powinny dobitnie pokazać, że wydajność w programach użytkowych czasem zależy w takim samym stopniu od techniki i staranności programowania, jak od użytego procesora. Testowanie procesorów, które uprawiają dziennikarze technologiczni jest jednocześnie testowaniem oprogramowania. Niezwykle rzadko zdarzają się programy do praktycznych zastosowań, co do których możemy mieć pewność, że w ramach obecnie dostępnych technik nie da się już wycisnąć dodatkowej wydajności, że wyciskają ostatnie soki z procesorów.

W testach procesorów używam nieco starszej, oficjalnej kompilacji Handbrake, z włączonymi wszystkimi optymalizacjami.

Ashes of the Singularity – optymalizacja dla Ryzen

W tym miejscu miał się skończyć ten wpis, ale wpadł mi w ręce kolejny przykład optymalizacji dla konkretnego procesora: wydana dzisiaj aktualizacja do gry Ashes of the Singularity. Ashes jest bardziej znane jako benchmark, niż gra, a jeśli wierzyć statystykom Steama, bardzo niewiele osób gra w nie regularnie (kilkanaście tysięcy w ciągu dwóch tygodni; obecnie kilkadziesiąt osób, z czego kilkunaście to na pewno maszyny testowe dziennikarzy). Wydana ostatnio aktualizacja zwiększa wydajność o nawet o 30% (patrz doniesienia prasowe).

We wbudowanym w grę benchmarku CPU (1920×1080, jakość Extreme, Radeon RX 480) Ryzen 7 1700X przyspieszył po aktualizacji o ponad 15%. Wydajność Core i7-7700K się nie zmieniła.

aots_avg

Mniejsza wartość na każdym słupku nie jest minimalną liczbą klatek! 33,0 na trzecim słupku oznacza, że przez 99% czasu rozgrywki (nie w 99% klatek) gra była wyświetlana z płynnością większą niż 33,0 kl./sek.

Najważniejszą zmianą po tej aktualizacji jest to, że czas renderowania klatki jest znacznie częściej ograniczony wydajnością karty graficznej, a nie wydajnością procesora.

Na poniższych wykresach im dalej w dół i na prawo sięga linia, tym lepiej. Większe wersje wykresów oraz wykres frametime w trakcie benchmarka znajdziecie w galerii, po kliknięciu na wykres. 

aots_1080_cpu_per7700k_1080_cpu_perCzasy renderowania klatek poprawiły się w każdym przypadku: nie tylko średnie, ale też te najdłuższe, gdzie procesor miał najwięcej do roboty. Widać to dokładnie na zbliżeniu na ostatnie 5%, czyli 5% czasu rozgrywki spędzonego przy najgorszej płynności.

aots_1080_cpu_per957700k_1080_cpu_per95

Taki wzrost wydajności to rzadko spotykana okoliczność. Jest częściej wynikiem usunięcia błędów albo nieuniwersalnych optymalizacji, którymi niechcący popsuto wydajność w niszowych przypadkach (nie twierdzę, ze w Ashes właśnie tak było). Byłoby zupełnie nierealistyczne oczekiwanie, że w wielu grach nastąpią podobne optymalizacje i podobnie zmienią się stosunki wydajnościowe między procesorami. Jednak jeśli kiedykolwiek deweloperzy gier mieliby to zrobić, to teraz mają najbardziej sprzyjające okoliczności. Już pojawienie się konsol i API DirectX 12 i Vulkan zmieniło sporo pod tym względem. Przyszłe generacje procesorów nie będą zasadniczo wydajniejsze w zadaniach jednowątkowych, ale będą miały więcej wątków, niż do tej pory można było się spodziewać w każdym segmencie cenowym. Jeśli deweloperzy chcą dysponować większą mocą obliczeniową, to będą musieli się pochylić nad optymalizacją – Intelowi i AMD coraz trudniej dostarczać jej rozwiązaniami sprzętowymi.

Podobnie jak w przypadku x265, Ashes to tylko jeden przykład sytuacji, w której oprogramowanie robi rożnicę większą, niż czasem między dwoma procesorami, których ceny różnią się o kilkaset złotych. Jak zawsze, mogę tylko rekomendować dobieranie procesora według swoich potrzeb, a nie według średnich ocen z recenzji. I nie zapomnijcie poświęcić tyle samo uwagi i czasu, żeby dobrać właściwe oprogramowanie (albo nawet więcej, bo przecież tak duża część oprogramowania jest za darmo i można je wypróbować bez straty...)!

Komentarze
Pawelek6
30 marca 2017, 21:22
Spoko się czyta i zgadzam się, że raczej rdzeni będzie nam teraz przybywać, a jeżeli mocy na wątek. No i zawsze pozostaje ta nieszczęsna kwestia optymalizacji, dosyć często olewana.
Poza tym, jakby komuś było mało tematu o 'ryżu', to na PPC jest jeszcze małe co nieco.
7
nirvan
30 marca 2017, 23:34
Fajny artykuł. Miło, że chciało Ci się kompilować handbrake :) a co do testu w nim - może w przypadku Ryzena wąskie gardło jest gdzie indziej niż w samym procesorze? Różnice pomiędzy różnymi wersjami są tak małe, że w sumie w granicach błędu... Wydaje mi się, że te 16 wątków Ryzena dostarcza na tyle dużo mocy przerobowych, że coś innego się zatyka.
10
EntuzjastaKpiny
30 marca 2017, 23:42
Prawda jest taka że jak ktoś potrzebuje sprzętu do konkretnych zastosowań to wie o tym wcześniej. Jak ogłaszają uczelnie czy firmy przetargi to zawsze da się znaleźć takie warunki przetargu żeby warunki idealnie odpowiadały określonym procesorom. Wystarczy wyznaczyć X pkt. w benchmarku Y zoptymalizowanym pod Intela żeby spływały oferty tylko z Intelem. I odwrotnie. Wiele razy byłem świadkiem przetargów gdzie placówki edukacyjne po prostu nie chciały AMD. Po to są te gówniane benchmarki typu BAPCo SYSMARK
Edytowane przez autora (2017.03.31, 01:07)
10
Fujiyama
31 marca 2017, 11:17
Nowa AGESA + planowane wsparcie DDR3600 powinna przynieść średno dodatkowe 2-5% wydajności. Microsoft też szykuje aktualizację W10, która przyspiesza Ryzena.
5
bv6t7
31 marca 2017, 12:25
Atak_Snajpera (2017.03.31, 11:47)
Autor tekstu nie potrzebnie sobie utrudnił życie z handbreakiem.


Mógł jeszcze dodać wyniki z twojego wątku/programu http://forum.pclab.pl/topic/1184884-x265-FHD-Benchmark/
5
pwil
31 marca 2017, 14:07
Przydałoby się jeszcze sprawdzenie ile pobierają Watów oba procesory i wyliczyć perf/watt.
5
BlackBishop
31 marca 2017, 17:14
Wypadało by w artykule podać jaki GCC i dokładnie jakie flagi.
3
Putout
31 marca 2017, 17:40
ext (2017.03.31, 13:20)
Trzeba było ograniczyć testy do jednego wątka, wtedy zminimalizowałbyś wąskie gardła. Ale rozumiem, że AMD zabroniło robić takie testy.


w domu wszyscy zdrowi? każdy wie że przewagia zena wychodzi od niższej ceny i więszkej ilości rdzeni. po co robić test na 1 rdzeń, gdy od 15 lat z czegoś takiego nie korzysta?

zenki są niezłe, ale prawdziwy test przyjdzie z r5 i r3, bo to cywilki schodzą najlkepiej. jeśli r5 będzie nieopłącalne to sory i cześć, ale amd będzie w dupe.
8
MGRIMAR
31 marca 2017, 23:48
Czy w końcu ktoś przetestuje procesory w grach ale z włączonym streamingiem na Youtuba? Sporo jest streamerów, których to by zainteresowało.
8
ext
1 kwietnia 2017, 01:39
Putout (2017.03.31, 17:40)
ext (2017.03.31, 13:20)
Trzeba było ograniczyć testy do jednego wątka, wtedy zminimalizowałbyś wąskie gardła. Ale rozumiem, że AMD zabroniło robić takie testy.


w domu wszyscy zdrowi? każdy wie że przewagia zena wychodzi od niższej ceny i więszkej ilości rdzeni. po co robić test na 1 rdzeń, gdy od 15 lat z czegoś takiego nie korzysta?

zenki są niezłe, ale prawdziwy test przyjdzie z r5 i r3, bo to cywilki schodzą najlkepiej. jeśli r5 będzie nieopłącalne to sory i cześć, ale amd będzie w dupe.


Liczyłem na rzetelne podejście do tematu optymalizacji. Jeśli przy 16 wątkach CPU nie było obciążone w 100% to śmiem twierdzić, że jednostki wykonawcze na coś czekały. Przy jednym wątku problemu by nie było. Nie obchodzi mnie w żaden sposób względna wydajność rożnych CPU. Fanatycy amd jednak od razu widzą w tym atak. Nie obchodzą mnie wasze durne wojenki.
0
AMDK11
1 kwietnia 2017, 02:38
Instrukcje AVX/AVX2+FMA będą z czasem w coraz to większym stopniu wspierane przez soft więc różnice między Core i(FPU 2x 256bit na każdy rdzeń(Haswell i nowsze)) a Ryzen(FPU 2x 128bit(4x64bit) na każdy rdzeń) będą coraz bardziej widoczne.
Właśnie dla tego pisałem już że procesory od generacji Haswell są bardziej przyszłościowe ze względu na FPU SIMD(AVX2+FMA) 2x 256bit(na każdy rdzeń) i cache L1 o 2x większej przepustowości co teoretycznie daje Core i7 4C/8T wydajność na poziomie Ryzen 7 8C/16T.
Edytowane przez autora (2017.04.01, 15:45)
2
mjwhite
1 kwietnia 2017, 04:54
http://i.imgsafe.org/41ba1e2822.png
Wystarczyło skorzystać z tego programiku żeby zauważyć że avx na ryzen niewiele daje względem sse.
0
Sleepy
1 kwietnia 2017, 10:45

Przepustowość określa, ile średnio takich instrukcji daje wynik w jednym cyklu zegara, w optymalnych warunkach.
Opóźnienie określa, ile cykli zegara średnio zajmuje wykonanie jakiejś instrukcji, od wysłania z kolejki mikrooperacji do otrzymania wyniku.

Wg tego co napisales, opoznienie, czyli latency, okreslona jest w jednostkach cykle / instrukcje, zas przepustowosc, czyli throughput, instrukcje / cykl. I to jest OK, tylko nalezy pamietac ze czesto w dokumetacji uzywana jest ta sama jednostka, czyli chyba najczesciej cykle / instrukcje i stad np intelowa instukcja AVXowa mnozaca 2 wektory floatow ma dla Haswella latency = 5 a throughput = 0.5, zas dla Broadwella latency = 3 a throughput = 0.5, czyli jeden i drugi w jednym takcie zegara potrafi wypluc z siebie 2 wyniki.

Wydajność AVX byłaby dwa razy większa, gdyby odpowiednie instrukcje SSE miały dokładnie taką samą przepustowość i takie samo opóźnienie, a w praktyce tak nie jest

A sprawdzales jak jest w praktyce ? Bo w wiekszosci przypadkow w praktyce tak wlasnie jest.
Przy zalozeniu odpowiednio duzego zadania i odpowiedniej organizacji warunkiem 2 krotnej przewagi AVX nad SSE jest przepustowosc a nie latencja.


Tymczasem rdzenie Zen mają 128-bitowe jednostki arytmetyczne, zoptymalizowane głównie pod kątem instrukcji FMA (mnożenie dwóch liczb i dodawanie trzeciej do wyniku). Zen może wykonać jendocześnie dwa 128-bitowe mnożenia z dodawaniem, ale 256-bitowe instrukcje są wykonywane „na raty”, w dwóch cyklach, tak jak w poprzednich procesorach AMD.

Warto dodac ze Intelowe CPU od Haswella w gore wykonuja jednoczesnie dwie 256bitowe instukcje FMA. Dlatego Ivytown pomimo tego ze ma AVX moze byc np przy mnozeniu macierzy (typowe uzycie FMA) 4x wolniejszy od Haswella, bo ten ma FMA.
Edytowane przez autora (2017.04.01, 10:46)
2
Promilus1984
3 kwietnia 2017, 08:23
Kilka wyjaśnień:
1. AVX nie wymusza typu 256bit (dodam packed! bo to nie jest traktowane jak rzeczywista skalarna wartość 256 bitowa tylko kilkuelementowy wektor danych 32/64bit)
2. AVX bazuje na poprzednich SSE rozszerzając je o dodatkowy rejestr docelowy - czyli nie musimy już robić a=a*b bo możemy c=a*b czyli bez nadpisywania danych źródłowych
3. Samo przestawienie flagi kompilatora nie ma większego sensu, kompilatory są potężne, ale nawet one nie rozwiną pętli obliczeniowej nastawionej na 4x32bit w 8x32bit wektory, tutaj są potrzebne konkretne zabiegi optymalizacyjne
4. Jeśli intel myślałby szczerze o mega popularyzacji AVX to nie blokowałby jej w tańszych produktach, szczególnie że te tańsze są jednymi z częściej kupowanych, w każdym razie w np. laptopach.
5. Popularne obliczenia bazują na 3-4 zmiennych np. argb, xyzw; nie kojarzę by 64 bitowa precyzja była w typowych zastosowaniach konieczna, w takim wypadku zaś spokojnie wystarczają wektory 4x32bit. Czyli SSE/AVX128 - starsza połówka 256bit FPU w intelach w tym momencie byłaby nieużywana. Jedyną sytuacją gdy intel w obliczeniach simd znacząco wyprzedzi amd będzie gdy soft rzeczywiście będzie wykorzystywał 8x32 lub co bardziej prawdopodobne 4x64 wektory.Wtedy AVX2 będzie pracował na miarę swoich możliwości, a pozostałe procesory (z celeronami i pentium włącznie) się zadławią. Niemniej oprócz softu symulacyjnego fizykę i być może raytrace/pathtrace, a także środowiska HPC nic nie wskazuje by aplikacje do użytku domowego (w tym gry) w tej chwili lub w ciągu najbliższych lat miały w tym kierunku iść. Ergo AVX2 nie powinien być argumentem dla użytkowników domowych czy pracowników biurowych. Z drugiej strony r7 nic im też nie oferuje, a r5 nie oferuje wiele więcej niż i5. Więc wybór będzie podyktowany głównie możliwości/cena + ewentualnie preferencje klienta.
10
Gambino
3 kwietnia 2017, 14:11
czy R5 będą szybsze od I5 w grach?
-2
waszu
4 kwietnia 2017, 19:31
raczej na pewno w tych w których i7 jest wyraźnie szybsze od i5
2
Gajeno
6 kwietnia 2017, 19:28
A ja podzielę się z wami nieco innym odkryciem, i chętnie byłbym wdzięczny za wytłumaczenie dlaczego tak się właśnie dzieje:

https://www.youtube.com/watch?v=TcdmeGOsnss
https://www.youtube.com/watch?v=RW-16vo-CUk
https://www.youtube.com/watch?v=HTsGMQWnxqg
Zwróćcie uwagę na zużycie procesora. Widać dobitnie że w wielu grach Ryzen ( w porównaniu do konstrukcji intela) się po prostu nudzi, co świadczy tylko o tym jaka moc drzemie w tych procesorach i jak niewiele (a może i wiele) trzeba aby ją ujarzmić.
Edytowane przez autora (2017.04.06, 19:29)
-3
AMDK11
10 kwietnia 2017, 00:50
Gajeno (2017.04.06, 19:28)
A ja podzielę się z wami nieco innym odkryciem, i chętnie byłbym wdzięczny za wytłumaczenie dlaczego tak się właśnie dzieje:

https://www.youtube.com/watch?v=TcdmeGOsnss
https://www.youtube.com/watch?v=RW-16vo-CUk
https://www.youtube.com/watch?v=HTsGMQWnxqg
Zwróćcie uwagę na zużycie procesora. Widać dobitnie że w wielu grach Ryzen ( w porównaniu do konstrukcji intela) się po prostu nudzi, co świadczy tylko o tym jaka moc drzemie w tych procesorach i jak niewiele (a może i wiele) trzeba aby ją ujarzmić.

Ryzen 5 1400 to 4 Rzdenie/8 Wątków a Core i5 to tylko 4 Rdzenie/4 Wątki więc jak gra pożytkuje tylko 2 lub 4 wątki to nie dziwota że Ryzen bardziej się nudzi a wydajności pojedynczego wątku(mikroarchiutektury rdzenia) nie oszukasz ;)
Edytowane przez autora (2017.04.10, 00:53)
1
mjwhite
12 kwietnia 2017, 09:28
Gajeno (2017.04.06, 19:28)
A ja podzielę się z wami nieco innym odkryciem, i chętnie byłbym wdzięczny za wytłumaczenie dlaczego tak się właśnie dzieje:

https://www.youtube.com/watch?v=TcdmeGOsnss
https://www.youtube.com/watch?v=RW-16vo-CUk
https://www.youtube.com/watch?v=HTsGMQWnxqg
Zwróćcie uwagę na zużycie procesora. Widać dobitnie że w wielu grach Ryzen ( w porównaniu do konstrukcji intela) się po prostu nudzi, co świadczy tylko o tym jaka moc drzemie w tych procesorach i jak niewiele (a może i wiele) trzeba aby ją ujarzmić.


50% ryzena to fizyczny rdzeń drugie 50% to logiczny rdzeń. Jak gra korzysta z maks.4 wątków to i5 ma 100% a ryzen 50% ale to nie oznacza że wykorzystywana jest połowa mocy procesora, bo pozostałe wątki logiczne nie mają takiego zapasu mocy co fizyczne. Mówiąc inaczej te 50% wolnych zasobów ryzena to góra z 10-15% możliwej wydajności do uzyskania.
0
Zaloguj się, by móc komentować