Rozdzielanie obliczeń na poszczególne rdzenie procesora

0

Witam,

Mam pytanie dot. tego w jaki sposób obliczenia rozdzielane są na poszczególne rdzenie procesora.
Powiedzmy, że mam duży system X, który dla uproszczenia jest uruchomiony jako jeden proces(w rzeczywistości oczywiście rzadko kiedy tak jest).
I teraz moje pytanie czy jako programiści możemy w jakiś sposób kontrolować to w jaki sposób obliczenia są rozkładane na poszczególne rdzenie czy jest to w całości zadanie systemu operacyjnego?
Domyślam się, że w mniej lub bardziej skomplikowany sposób możemy tego dokonać, a całość związana jest z dziedziną tzw. programowania równoległego.
Jeśli możemy to kontrolować to czy jest to gra warta świeczki?

Przeczytałem sporo w Internecie na ten temat jednak nigdzie nie znalazłem jednoznacznej odpowiedzi.
Dowiedziałem się jedynie o opcji koligacji procesów co wskazywałoby, że system jednak daję radę sam z rozdzieleniem obliczeń na rdzenie.

Być może moje pytanie zawiera trochę niespójności lub nawet fałszywych stwierdzeń, za co przepraszam i prosiłbym o sprostowanie :)

Czy mógłby mi ktoś na chłopski rozum w skrócie wyjaśnić jak to działa? Lub też podać wiarygodne źródła?

Pozdrawiam

3
Ewaryst Ławecki napisał(a):

I teraz moje pytanie czy jako programiści możemy w jakiś sposób kontrolować to w jaki sposób obliczenia są rozkładane na poszczególne rdzenie czy jest to w całości zadanie systemu operacyjnego?

Lekko upraszczając, żeby system mógł rozdzielić obliczenia na rdzenie, to te obliczenia muszą być wykonywane w osobnych wątkach.
Czyli jeżeli aplikacja tworzy kilka wątków i w każdym równolegle przeprowadza część obliczeń, system automatycznie rozdzieli wątki na różne rdzenie.

0

@Azarien: To by się faktycznie układało w logiczną całość :) Dzięki!

7

Jeśli pytasz tylko o to, czy da się - tak, dostałeś już nawet link do pojęcia, sam też coś znalazłeś. Generalnie dać się da, zarówno dla procesów jak i wątków.

Czy gra warta świeczki i czy jest sens to robić... Obawiam się że bardzo mocno to zależy - od różnych czynników

  • architektury sprzętu - np. tego czy masz jeden CPU wielordzeniowy, czy kilka w UMA / NUMA / ccNUMA / rozproszonych w sieci, choćby i lokalnej, a jeśli masz na myśli kawałek kodu który dałoby się np. przenieść na GPGPU to tam zrównolegla się zupełnie inaczej, niż na procesorach (inny model wykonania, inny dostęp do pamięci przez jednostki obliczeniowe czy jak tam je zwał), no i znów będzie się liczyła komunikacja CPU/GPU - magistrala może być poważnym wąskim gardłem.
  • Czasu życia tych procesów (dla bardzo krótko żyjących procesów znaczną część zasobów i czasu zajmie... Ich tworzenie)
  • Liczby procesów i CPU/rdzeni - więcej nie zawsze znaczy lepiej, im więcej tym mniejszy zysk dla zadania tej samej wielkości, no i tym większy narzut na ewentualną komunikację. Jeśli procesów jest dużo więcej niż rdzeni to i tak nie unikniesz przełączania kontekstu (pomijając to, że nawet mając pinning nie wykluczasz że scheduler odbierze procesowi CPU)
  • Tego co tak naprawdę jest wąskim gardłem aplikacji tudzież fragmentu aplikacji - jeśli procesy są głównie bezczynne bo czekają na dostępy do pamięci, to zrównoleglanie niewiele da, podobnie gdy głównym blokerem są operacje I/O np. sieć. Potencjalnie możesz nawet zaszkodzić dorzucając więcej procesów.
  • Sposobu rozdzielania zadań między procesy tzn dzielenie na więcej mniejszych zadań lub kilka dużych, rozdzielanie stałej liczby zadań do każdego procesu lub balansowanie obciążenia, tworzenie osobnego procesu dla każdego zadania lub ponowne wykorzystanie np w ramach puli procesów itd

Generalnie jednoznacznej odpowiedzi raczej nie da się udzielić, więc najrozsądniej zrobić parę podstawowych rzeczy, w miarę możliwości

  • Sprofilować aplikację i zobaczyć, co tak naprawdę jest najbardziej czasochłonne i jakie zasoby są najbardziej zżerane
  • Zrobić benchmark na konkretnym sprzęcie, zastosować kilka rozwiązań i zmierzyć jakie są różnice
  • Potencjalnie przyjrzeć się temu, jak zadanie jest zdefiniowane i czy będzie się ładnie zrównoleglać tzn nie ma zbyt dużo synchronizacji / komunikacji. Najlepiej żeby nie było wcale, wtedy zrównoleglanie jest trywialne i przy okazji bardziej bezpieczne, niż gdy trzeba się komunikować. Być może ma dobrą złożoność, ale przez narzut komunikacji będzie się źle skalować i zrównoleglać ;)

Właściwie, to wiedząc jaka jest złożoność obliczeniowa zadania w wersji jedno-procesowej, pod-zadania w wersji zrównoleglonej i jakie są narzuty na komunikację w relacji do liczby procesów / rozmiaru zadania i tak dalej jesteś w stanie określić analitycznie, czy zadanie będzie się dobrze zrównoleglać lub czy/jak będzie się skalować ze wzrostem rozmiaru zadania, i tym podobne.

0

@superdurszlak: Również dziękuję za odpowiedź, wiele mi to rozjaśnia. Mogę zgłębiać dalej :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1