Ile wysiłku powinniśmy poświęcić programowaniu wielu rdzeni?

12

W dzisiejszych czasach procesory mają coraz więcej rdzeni, co mnie zastanawia ...

Czy my, programiści, powinniśmy dostosować się do tego zachowania i poświęcić więcej wysiłku na programowanie wielu rdzeni?

W jakim stopniu powinniśmy to zrobić i zoptymalizować? Wątek? Powinowactwo? Optymalizacje sprzętowe? Coś innego?

Tamara Wijsman
źródło

Odpowiedzi:

15

Bez względu na to, jak dobry jesteś, prawdopodobnie nie znajdziesz lepszego schematu zarządzania wątkami itp. Niż zespołów opracowujących język i kompilator, w którym piszesz swój kod.

Jeśli potrzebujesz aplikacji wielowątkowej, utwórz potrzebne wątki i pozwól kompilatorowi i systemowi operacyjnemu wykonywać swoje zadania.

Musisz być świadomy sposobu zarządzania tymi wątkami, abyś mógł jak najlepiej wykorzystać zasoby. Przykładem może być nie tworzenie zbyt wielu wątków.

Musisz także zdawać sobie sprawę z tego, co się dzieje (patrz komentarz Lorenza), abyś mógł udzielać wskazówek do zarządzania wątkami (lub zastąpić je w szczególnych przypadkach), ale pomyślałem, że będzie ich niewiele.

ChrisF
źródło
3
Ale wątek stale przeskakujący z rdzenia na drugi będzie podlegał karom wydajności (z powodu pominiętej pamięci podręcznej procesora pierwszego i drugiego poziomu), szczególnie w architekturach, w których stosuje się dwie różne fizyczne matryce. W wielowątkowym kodzie intensywnym powinowactwo jest dobrą rzeczą.
Wizard79
@Lorenzo - W takim przypadku musisz sprawdzić, czy możesz powiązać nić z pojedynczym rdzeniem - co może być przypadkiem specjalnym - ale interesującym.
ChrisF
1
Czy nie byłoby dziwnym posunięciem dla systemu operacyjnego, aby kontekstowo przełączać aktywny wątek z jednego rdzenia na inny?
JBRWilkinson,
Zgadzam się z @JBRWilkinson, powinowactwo wątków wydaje mi się zadaniem systemu operacyjnego.
Collin
1
@JBRWilkinson Pod linuksem (i myślę, że większość systemów operacyjnych) wątki przeskakują między rdzeniami przez cały czas. Pierwszym powodem jest to, że masz o wiele więcej wątków niż rdzeni. A jeśli niektóre wątki umrą, musisz się zrównoważyć. Drugim powodem jest to, że wiele wątków śpi. A kiedy niektórzy się obudzą, jądro może myśleć, że jeden rdzeń ma większe obciążenie niż inne i przenosi wątek, często twój wątek obliczeniowy procesora. Następnie 2 wątki rozpruwające procesor działają na tym samym rdzeniu, dopóki jądro nie cofnie się o jeden. Jeśli dzielisz duże zadanie na dokładnie takie same liczby rdzeni, to chcesz ustawić powinowactwo wątku.
Goswin von Brederlow,
5

Jestem programistą .NET i wiem, że .NET ma abstrakcję wysokiego poziomu dla wielowątkowości o nazwie Zadania. Chroni Cię przed zbyt dużą wiedzą na temat prawidłowego wielowątkowości w stosunku do metalu. Zakładam, że inne obecne platformy programistyczne mają podobne abstrakcje. Więc jeśli zamierzasz zrobić coś z wielowątkowością, postaram się pracować na tym poziomie, jeśli to w ogóle możliwe.

Teraz na pytanie, czy warto dbać o wielowątkowość w konkretnej aplikacji. Odpowiedź na to pytanie zależy w dużej mierze od aplikacji, którą piszesz. Jeśli piszesz aplikację przetwarzającą tysiące (lub więcej) niezależnych rzeczy, a przetwarzanie to można wykonać równolegle, prawie na pewno zyskasz na wielowątkowości. Jeśli jednak piszesz prosty ekran do wprowadzania danych, wielowątkowość może Cię nie kupić.

Przynajmniej pracując nad interfejsem użytkownika, musisz pamiętać o wielowątkowości. Nie chcesz odpalać długotrwałej operacji z interfejsu użytkownika i spowodować, że przestanie ona odpowiadać, ponieważ przejąłeś wątek interfejsu użytkownika, aby wykonać tę operację. Odpal wątek w tle i przynajmniej daj użytkownikowi przycisk Anuluj, aby nie musiał czekać na zakończenie, jeśli popełni błąd.

RationalGeek
źródło
5

W krainie Objective-C, Mac OS X i iOS, frameworki (podobnie jak wiele innych) są napisane, aby wykorzystać wzrost liczby rdzeni procesora i dać programistom przyjemny interfejs do ich wykorzystania.

Przykładem w Mac OS X i iOS jest wysyłka Grand Central. Są dodatki libc(jak sądzę), aby ułatwić wielowątkowość opartą na kolejce. Następnie frameworki Cocoa i Foundation (między innymi) są zapisywane na GCD, zapewniając deweloperowi łatwy dostęp do kolejek wysyłkowych i wątków z bardzo małym kodem płyty kotłowej.

Wiele języków i ram ma podobne koncepcje.

Jasarien
źródło
5

Trudność polega na podzieleniu algorytmu intensywnego procesora na fragmenty wykonania, które można wątkować.

Wówczas wątek ciągle przeskakujący z rdzenia na drugi będzie podlegał karom wydajności (z powodu pominiętej pamięci podręcznej procesora pierwszego i drugiego poziomu), szczególnie w architekturach, w których stosuje się dwie różne fizyczne matryce. W tym przypadku powinowactwo wątek-rdzeń jest dobrą rzeczą.

Wizard79
źródło
3

Jesteśmy teraz (październik 2010 r.) W czasach ogromnej transformacji.

Mogliśmy dziś kupić 12-rdzeniowy komputer stacjonarny.
Mogliśmy zakup dzisiaj przetwarzanie 448 Rdzeń karty (szukaj NVIDIA Tesla).

Istnieją ograniczenia dotyczące tego, na ile my, programiści, możemy pracować, ignorując niezwykle równoległe środowiska, w których nasze programy będą działać w najbliższej przyszłości.

Systemy operacyjne, środowiska wykonawcze i biblioteki programowania mogą tylko tyle zrobić.

W przyszłości będziemy musieli podzielić nasze przetwarzanie na odrębne porcje w celu niezależnego przetwarzania, używając abstrakcji takich jak nowy .NET „Task Framework”.

Szczegóły, takie jak zarządzanie pamięcią podręczną i koligacja, będą nadal obecne - ale będą one tylko dowodem działania bardzo wydajnej aplikacji. Żaden sam programista nie będzie chciał ręcznie zarządzać tymi szczegółami na 10-rdzeniowej maszynie.

Bevan
źródło
3

cóż, to naprawdę zależy od tego, co rozwijacie. odpowiedź, w zależności od tego, co opracowujesz, może wahać się od „nieistotna” do „absolutnie krytyczna i oczekujemy, że wszyscy w zespole będą dobrze rozumieć i wykorzystywać równoległe implementacje”.

w większości przypadków solidne zrozumienie i stosowanie blokad, wątków oraz zadań i pul zadań będzie dobrym początkiem, gdy będzie wymagana potrzeba równoległości. (zależy od języka / lib)

dodaj do tego różnice w projektach, które musisz wykonać - w przypadku nietrywialnego przetwarzania wieloprocesowego często trzeba nauczyć się kilku nowych modeli programowania lub strategii paralelizacji. w takim przypadku czas na naukę, wystarczająco dużo czasu, aby mieć solidne zrozumienie i aktualizację istniejących programów, może zająć zespołowi przez rok (lub dłużej). po osiągnięciu tego punktu (miejmy nadzieję!) nie dostrzeżesz ani nie podejdziesz do problemów / wdrożeń tak, jak robisz to dzisiaj (pod warunkiem, że jeszcze tego nie zrobiłeś).

Kolejną przeszkodą jest to, że skutecznie optymalizujesz program do określonego wykonania. jeśli nie masz dużo czasu na optymalizację programów, to tak naprawdę nie skorzystasz z niego tak dobrze, jak powinieneś. wysoki poziom (lub oczywista) równoległość może poprawić postrzeganą prędkość twojego programu przy dość niewielkim wysiłku, i to tyle, ile pójdzie dziś wiele zespołów: „Zrównolegliliśmy naprawdę oczywiste części aplikacji” - w niektórych przypadkach jest to w porządku. czy korzyść z przyjęcia nisko wiszących owoców i zastosowania prostej paraliżacji będzie proporcjonalna do liczby rdzeni? często, gdy istnieją dwa do czterech rdzeni logicznych, ale nie tak często. w wielu przypadkach jest to akceptowalny zwrot, biorąc pod uwagę inwestycję czasu. ten model równoległy jest wprowadzeniem wielu ludzi do wdrażania dobrych zastosowań równoległości.

czego nauczysz się dzięki tym trywialnym równoległym modelom, nie będą idealne we wszystkich złożonych scenariuszach równoległych; skuteczne stosowanie złożonych równoległych projektów wymaga znacznie innego zrozumienia i podejścia. te proste modele są często odłączane lub mają trywialną interakcję z innymi komponentami systemu. również wiele implementacji tych trywialnych modeli nie skaluje się dobrze w celu skutecznego złożonego układu równoległego - wykonanie złego złożonego równoległego projektu może zająć tyle samo czasu co wykonanie modelu prostego. ill: wykonuje dwa razy szybciej niż model jednowątkowy, wykorzystując 8 rdzeni logicznych podczas wykonywania. najbardziej powszechne przykłady wykorzystują / tworzą zbyt wiele wątków i wysoki poziom zakłóceń synchronizacji. ogólnie jest to określane jako spowolnienie równoległe. dość łatwo można go spotkać, jeśli wszystkie równoległe problemy traktuje się jak zwykłe problemy.

powiedzmy więc, że naprawdę powinieneś wykorzystywać efektywny wielowątkowość w swoich programach (mniejszość, w dzisiejszym klimacie): będziesz musiał efektywnie zastosować prosty model, aby nauczyć się modelu złożonego, a następnie ponownie nauczyć się, jak podchodzić do przebiegu programu i interakcji. model złożony to miejsce, w którym powinien ostatecznie znajdować się Twój program, ponieważ tam właśnie znajduje się sprzęt i tam będą wprowadzane najbardziej dominujące ulepszenia.

wykonanie prostych modeli można sobie wyobrazić jak widelec, a złożone modele działają jak złożony ekosystem. myślę, że zrozumienie prostych modeli, w tym ogólnego blokowania i wątków, powinno lub będzie się wkrótce spodziewać od pośrednich programistów, gdy domena (w której tworzysz) używa go. zrozumienie złożonych modeli jest wciąż nieco niezwykłe (w większości domen), ale myślę, że popyt wzrośnie dość szybko. jako programiści znacznie więcej naszych programów powinno obsługiwać te modele, a większość zastosowań jest daleko w tyle za zrozumieniem i wdrożeniem tych koncepcji. Ponieważ liczba logicznych procesorów jest jednym z najważniejszych obszarów poprawy sprzętu, zapotrzebowanie na osoby rozumiejące i potrafiące wdrażać złożone systemy z pewnością wzrośnie.

wreszcie wiele osób uważa, że ​​rozwiązaniem jest „dodanie równoległości”. często lepiej jest przyspieszyć istniejącą implementację. w wielu przypadkach jest to o wiele łatwiejsze i prostsze. wiele programów na wolności nigdy nie zostało zoptymalizowanych; niektórzy ludzie odnieśli wrażenie, że niedopuszczona wersja zostanie wkrótce przyćmiona przez sprzęt. poprawa projektu lub algorytmów istniejących programów jest również ważną umiejętnością, jeśli wydajność jest ważna - rzucanie większej liczby rdzeni w problemy nie musi być najlepszym lub najprostszym rozwiązaniem.

podczas atakowania na nowoczesne komputery PC większość z nas, którzy muszą wdrożyć dobre systemy równoległe, nie będzie musiała wychodzić poza wielowątkowość, blokowanie, biblioteki równoległe, wartość książki do przeczytania oraz duże doświadczenie w pisaniu i testowaniu programów (zasadniczo znacznie zmieniając sposób, w jaki programy do pisania).

justin
źródło
2

Robimy, ale piszemy ciężkie oprogramowanie do obliczeń, więc korzystamy bezpośrednio z wielu rdzeni.

Czasami program planujący często przenosi wątki między rdzeniami. Jeśli nie jest to do zaakceptowania, możesz grać z podstawową powinowactwem.

Toon Krijthe
źródło
0

Na obecnym etapie częstotliwość procesora nie wzrośnie w najbliższej przyszłości. Utknęliśmy wokół znaku 3 GHz (bez podkręcania). Z pewnością w wielu aplikacjach może nie być konieczne wyjście poza bardzo proste wielowątkowość. Oczywiście, jeśli budujesz aplikację interfejsu użytkownika, każde intensywne przetwarzanie powinno odbywać się w wątku w tle.

Jeśli budujesz aplikację przetwarzającą ogromne ilości danych, które muszą być w czasie rzeczywistym, to tak, prawdopodobnie powinieneś przyjrzeć się programowaniu wielowątkowemu.

W przypadku programowania wielowątkowego przekonasz się, że będziesz otrzymywać malejące zwroty z wydajności; możesz spędzić godziny i ulepszyć program o 15%, a następnie spędzić kolejny tydzień i poprawić go tylko o kolejne 5%.

Złupić
źródło