Przejdź do treści

Skalowalność

Wprowadzenie

W kontekście znacznej równoległości obliczeń oferowanej przez współczesne komputery (wielordzeniowość/akceleratory), a szczególnie w kontekście środowiska HPC (wiele serwerów obliczeniowych), skalowalność obliczeń (scalability) to kluczowa cecha charakteryzująca zachowanie aplikacji. Jest to określenie w jakim stopniu dany program potrafi wykorzystywać dużą ilość zasobów obliczeniowych.

Testy skalowalności polegają na zbadaniu przyspieszenia/wydajności aplikacji uruchamianej na coraz większej ilości zasobów obliczeniowych (CPU lub GPU). Przykładowo sprawdza się wydajność dla 1 rdzenia CPU, następnie dla 2, 4, 8, itd. Wyróżnia się dwa pojęcia:

  • skalowalność silna (strong scaling) – dla danego problemu (o ustalonym rozmiarze) odpowiada na pytanie "jakie przyspieszenie możemy uzyskać poprzez użycie większej liczby zasobów obliczeniowych?"
  • skalowalność słaba (weak scaling) – dla danego typu obliczeń, odpowiada na pytanie "czy zwiększając liczbę zasobów możemy w podobnym czasie rozwiązać problem o większym rozmiarze?"

IMAGE

skalowalność aplikacji CASTEP 17.1 względem wydajności dla 6144 rdzeni

Konwencja

Potocznie skalowalność utożsamia się z silną skalowalnością. W tym tekście stosujemy się do tej konwencji. Kiedy odwołujemy się do słabej skalowalności piszemy o tym wprost.

Naturalne oczekiwanie jest takie, że jeśli weźmiemy dwukrotnie więcej zasobów obliczeniowych do rozwiązania tego samego problemu to czas obliczeń powinien skrócić się o połowę (dwukrotne przyspieszenie). Alternatywnie, oczekujemy że w tym samym czasie będziemy mogli policzyć dwukrotnie większy układ. Zwykle tak nie jest, dlatego taką sytuację określa się mianem "idealnej/doskonałej skalowalności":

  • idealna / doskonała skalowalność (ideal / perfect scaling) - zachodzi gdy dla ustalonego problemu obliczeniowego, zwiększenie liczby zasobów n-razy, skutkuje n-krotnym przyspieszeniem.

Szczegóły

Skalowalność aplikacji odpowiada temu na ile dobrze aplikacja potrafi się zrównoleglać. Im lepsze zrównoleglenie aplikacji, tym jest ona bardziej zdolna do wykorzystywania dużej ilości zasobów obliczeniowych – wraz z ich wzrostem potrafi liczyć szybciej (silna skalowalność) lub rozwiązywać większe układy (słaba skalowalność). W przypadku korzystania z superkomputera jest to kluczowa cecha.

Porada

Znajomość skalowalności pozwala na odpowiednie dobranie zasobów obliczeniowych. Jeśli program nie zrównolegla się dobrze, zwiększenie zasobów nie pomoże w szybszym ukończeniu obliczeń.

Obserwacja – słaba a silna skalowalność

Jeśli czas wykonania obliczeń wzrasta liniowo wraz ze zwiększeniem rozmiaru problemu, silna skalowalność implikuje słabą.

Przyspieszenie

Skalowalność można prezentować poprzez wykres czasu wykonania aplikacji (oś y) względem liczby wykorzystanych zasobów (oś x), jednak najczęściej jest ona prezentowana w oparciu o przyspieszenie – tego typu wykresu są bardziej powszechne i bardziej intuicyjne ("więcej znaczy lepiej").

Przyspieszenie (speedup) jest miarą ile razy szybciej wykona się program w jednym wariancie względem drugiego. Dla skalowalności określamy

  • – czas wykonania wersji bazowej (zwykle na jednym rdzeniu / karcie GPU lub na jednym pełnym węźle obliczeniowym)
  • – czas wykonania obliczeń dla n-krotnego zwiększenia liczby zasobów obliczeniowych

Przy takich oznaczeniach, przyspieszenie to po prostu stosunek tych wartości.

Alternatywnie, zamiast czasów wykonania, dla danej aplikacji wygodniejsze może być porównywanie uzyskanej wydajności obliczeń, przykładowo wartości FLOPS lub ns/day (GROMACS) czy tokens/s (trening sieci). Efektywnie iloraz tych wartości sprowadza się do ilorazu czasu wykonania.

Liniowe przyspieszenie

Idealna skalowalność odpowiada funkcji liniowej . Jest to liniowe przyspieszenie (linear speedup).

W przypadku słabej skalowalności, stosunek czasów wykonania wyrażony przez jest nazywany efektywnością; w oparciu o nią prezentuje się wykres skalowalności.

Efektywność

Na bazie przyspieszenia można wyznaczyć kolejną wartość – efektywność zrównoleglenia (parallel efficiency). Charakteryzuje ona "jak dobre" jest zrównoleglenie, tj. na ile efektywnie zostały wykorzystane dodatkowe zasoby obliczeniowe.

Wyznaczamy ją jako iloraz przyspieszenia i liczby dodatkowych procesorów, wartość można podawać jako ułamek lub w procentach. Spodziewamy się że maksymalna efektywność to 1 – odpowiada ona idealnemu skalowaniu. Więcej patrz: parallel efficiency.

Dla testów słabej skalowalności, efektywność jest zdefiniowana jako , tj. nie ma potrzeby dzielenia tej wartości przez liczbę procesorów.

Typowy wykres

Badając skalowalność aplikacji dla konkretnego problemu o ustalonym rozmiarze, wraz ze wzrostem liczby zasobów (oś x) można spodziewać się następujących prawidłowości:

  • początkowo przyspieszenie rośnie liniowo (im nachylenie bliższe idealnej prostej tym lepiej)
  • stopniowo wzrost wydajności zaczyna spowalniać (nachylenie krzywej się zmniejsza)
  • od pewnego momentu następuje wypłaszczenie (brak przyspieszenia)
  • dalej następuje załamanie wydajności i przyspieszenie zaczyna spadać

IMAGE

przykład skalowalności - załamanie nastąpiło po przekroczeniu 128 procesorów [źródło]

Interpretacja wykresu

Stopniowe spowolnienie na wykresie oznacza systematyczny wzrost narzutu zrównoleglenia oraz to że zaczyna dominować część obliczeń która nie jest zrównoleglona. Po przekroczeniu pewnego punktu, narzut jest tak duży, że czas obliczeń ulega wydłużeniu.

Takie zachowanie odpowiada następującym efektom:

  • narzut zrównoleglania – zrównoleglanie obliczeń pociąga za sobą dodatkową pracę potrzebną do podziału zadania na mniejsze i koordynacji większej liczby procesorów; w tym zakresie mogą pojawić się problemy dotyczące:

    • ograniczonej przepustowości sieci - wzrost liczby danych przesyłanych między wieloma węzłami,
    • dostępu do pamięci - więcej procesów próbuje uzyskać dostęp i aktualizuje te same dane w pamięci,
    • dostępu do dysku - większa liczba operacji I/O.
  • rozmiar problemu – dla problemu o ustalonym rozmiarze, nie da się go dzielić na dowolnie małe części, przy pewnym rozmiarze dalsze jego zmniejszanie nie jest opłacalne;

  • część sekwencyjna – dana aplikacja może posiadać fragmenty obliczeń, które nie są zrównoleglone, patrz prawo Amdahla.

Porada

Oceniając wyniki pomiaru skalowalności zawsze należy brać pod uwagę rozmiar problemu. Wykres skalowalności dla problemu o większym rozmiarze może wyglądać bardziej korzystnie.

Przyspieszenie superliniowe

Czasami jest możliwe zaobserwowanie przyspieszenia lepszego niż idealne. Mówimy wtedy, że wystąpiło przyspieszenie superliniowe (super-linear speedup). Ten bardzo korzystny ale rzadki efekt zwykle jest spowodowany efektem dostępu do pamięci. Wraz ze wzrostem liczby procesorów, rozmiar zadania per procesor maleje – w pewnym momencie może okazać się że jest on na tyle mały, że wszystkie dane mieszczą się w jego pamięci cache, co powoduje znaczne przyspieszenie w obliczeniach.

IMAGE

przyspieszenie superliniowe zaobserwowane dla części programu ADF przy odpowiednio dużej liczbie rdzeni

Limity skalowalności – prawo Amdahla

Aplikacje zwykle składają się z serii kroków. Przykładowo: wczytanie danych, wstępne przetworzenie, właściwe obliczenia, zapis wyników. Najczęściej każda z faz ma inną charakterystykę skalowalności. Oprócz tego aplikacja może w pewnym stopniu wykonywać sekwencyjne obliczenia – czyli posiadać partie kodu, które nie są zrównoleglone.

Prawo Amdahla opisuje bardzo naturalną i praktyczną obserwację dotyczącą takiej sytuacji – niezależnie od liczby wykorzystanych zasobów obliczeniowych, możliwość skalowania obliczeń jest ograniczona przez występowanie części sekwencyjnych. Zależność ta jest wyrażona prostym równaniem:

gdzie:

  • - teoretyczne przyspieszenie aplikacji dla n procesorów,
  • - odsetek programu, który jest wykonywany sekwencyjnie,
  • - odsetek programu, który można zrównoleglić (),
  • - ilość użytych rdzeni.

IMAGE

możliwe do osiągnięcia przyspieszenie dla 4 aplikacji posiadających różne odsetki części zrównoleglonych (parallel portion)

Przykład prostego zastosowania

Jeżeli część sekwencyjna wykonuje się przez 30 min, wtedy nawet przy nieskończonej ilości rdzeni, czas wykonania nie spadnie poniżej 30 min. Jeśli więc wersja szeregowa programu (tj. obliczenia tylko na jednym rdzeniu) trwa 2 godziny, to maksymalnie możemy uzyskać czterokrotne przyspieszenie.

Użyteczność obserwacji wyrażonej przez prawo Amdahla jest dwojaka:

  • w odniesieniu do aplikacji już zrównoleglonej, poprzez wyznaczenie maksymalnego teoretycznego przyspieszenia, pozwala ocenić czy aktualnie uzyskiwana skalowalność jest dobra czy nie;
  • w odniesieniu do kodu który dopiero ma być zrównoleglony, pozwala ocenić jaki może być potencjalny zysk i wybrać do zrównoleglenia te części kodu, które odpowiadają za największą proporcjonalnie część obliczeń.

Należy zwrócić uwagę, że prawo Amdahla nie bierze pod uwagę narzutu zrównoleglenia i faktyczne przyspieszenie zazwyczaj jest mniejsze niż teoretyczne. Jednocześnie przyrównywanie uzyskanego przyspieszenia do teoretycznego może być dobrym sposobem na ocenę jakości implementacji zrównoleglenia i obserwację czy nie generuje ona zbytniego narzutu. Może pozwolić to zlokalizować potencjalne miejsce do optymalizacji.

Testy skalowalności

Znajomość skalowalności aplikacji jest niezbędna do prawidłowego przewidywania czasu wykonywania programu i w doborze adekwatnych zasobów obliczeniowych. W kontekście prowadzenie obliczeń w środowisku HPC warto myśleć o tym jako o obowiązkowym punkcie, przed zleceniem zasadniczych obliczeń.

Marnowanie zasobów

Wykonywanie obliczeń na zbyt dużych zasobach, w sytuacji gdy aplikacje się nie skaluje, prowadzi do marnowania zasobów obliczeniowych i niepotrzebnego zużycia prądu.

Aby poznać jaka jest skalowalność aplikacji, po pierwsze - w przypadku korzystania z zewnętrznego oprogramowania - warto poszukać materiałów opisujących testy skalowalności wykonane przez innych użytkowników lub twórców danego oprogramowania. Należy jednak pamiętać, że dla aplikacji wielozadaniowych skalowalność różnych metod obliczeniowych może znacznie się od siebie różnić. Oprócz tego – szczególnie w przypadku własnego kodu – warto samemu wykonać testy skalowalności.

O testach skalowalności dobrze myśleć w dwóch skalach:

  1. skalowalność w obrębie jednego węzła – w takich testach badamy skalowalność zaczynając od wydajności wersji szeregowej (tj. wykonywanej tylko na jednym rdzeniu CPU / jednej karcie GPU), po czym zwiększamy liczbę rdzeni stopniowo, aż do wykorzystania wszystkich rdzeni z danego węzła obliczeniowego;
    • przy obecnych procesorach dla serwerów obliczeniowych, uzyskanie pełnej skalowalności w obrębie węzła już jest wyzwaniem; przykładowo superkomputer Helios w ACK Cyfronet AGH jest wyposażony w serwery posiadające aż 192 rdzenie CPU;
  2. skalowalność na więcej węzłów – w takich testach jako bazową wydajność (czas wykonania) przyjmujemy wydajność uzyskaną dla obliczeń które wykorzystały wszystkie zasoby z jednego węzła obliczeniowego; kolejne testy wykonujemy zwiększając liczbę użytych węzłów (2 węzły, 4, 8, itd.).

Najważniejszym celem testów skalowalności jest zidentyfikowanie punktu w którym zysk z dodania kolejnych zasobów przestaje przynosić istotne przyspieszenie, patrz typowy wykres. Nie należy zlecać zadań o liczbie zasobów przekraczających punkt załamania!.

Linki


Ostatnia aktualizacja: 4 kwietnia 2025