Jak wyartykułować różnicę między programowaniem asynchronicznym a równoległym?

139

Wiele platform promuje asynchroniczność i równoległość jako sposób na poprawę responsywności. Ogólnie rozumiem różnicę, ale często trudno mi to wyrazić we własnym umyśle, jak również w przypadku innych.

Jestem programistą na co dzień i dość często używam asynchronii i wywołań zwrotnych. Równoległość wydaje się egzotyczna.

Ale wydaje mi się, że można je łatwo łączyć, zwłaszcza na poziomie projektowania języka. Chciałbym mieć jasny opis ich relacji (lub nie) oraz klas programów, w których każdy z nich jest najlepiej stosowany.

Matt Sherman
źródło
Napisałem post na blogu na temat relacji między programowaniem asynchronicznym i równoległym - anat-async.blogspot.com/2018/08/…
Alexei Kaigorodov
6
równoległość występuje wtedy, gdy rzeczy dzieją się jednocześnie. Asynchroniczność występuje wtedy, gdy nie zawracasz sobie głowy czekaniem, aż wynik działania będzie kontynuowany. Po prostu kładziesz się spać i w pewnym momencie później przychodzi wynik, dzwoni dzwonek, budzisz się i kontynuujesz od tego momentu. Wykonywanie asynchroniczne może doskonale przebiegać szeregowo tylko w jednym wątku. (to jest prawie to, co robi javascript)
Thanasis Ioannidis

Odpowiedzi:

87

Kiedy uruchamiasz coś asynchronicznie, oznacza to, że nie blokuje, wykonujesz to bez czekania na zakończenie i kontynuujesz inne rzeczy. Paralelizm oznacza uruchamianie wielu rzeczy jednocześnie, równolegle. Równoległość działa dobrze, gdy można podzielić zadania na niezależne części pracy.

Weźmy na przykład renderowanie klatek animacji 3D. Renderowanie animacji zajmuje dużo czasu, więc jeśli uruchomisz ten render z poziomu oprogramowania do edycji animacji, upewnij się, że działa asynchronicznie, aby nie blokował interfejsu użytkownika i mógłbyś kontynuować inne rzeczy. Teraz każdą klatkę tej animacji można również traktować jako indywidualne zadanie. Jeśli mamy wiele procesorów / rdzeni lub wielu maszyn, możemy renderować wiele ramek równolegle, aby przyspieszyć ogólne obciążenie.

CodeMan
źródło
Zobaczę, czy to dostanę. Równoległe zadania renderowania różnych ramek powinny być rozłożone na wiele procesorów / rdzeni. Nie ma to nic wspólnego z czasem wykonania zadania ani z tym, czy to zadanie blokuje coś innego. Oznacza to po prostu, że kilka procesorów zrobi to razem i udostępni wynik, jakby działał na jednym super szybkim procesorze. Dobrze?
1
„Renderowanie animacji zajmuje dużo czasu, więc jeśli miałbyś uruchomić ten render z poziomu oprogramowania do edycji animacji, upewnij się (...)”. Co?
Odnośnie do animacji 3D: Przede wszystkim NIGDY nie uruchamiałbyś programu do grafiki 3D z generowaniem klatek na CPU - każda rozsądna osoba od razu zasugerowałaby użycie GPU. Po drugie, gdybyśmy to zrobili (bardzo odradzane), użylibyśmy licznika czasu do pomiaru liczby klatek, które możemy wyrenderować, w przeciwnym razie moglibyśmy po prostu zbudować stos niedokończonych wywołań renderowania Tasks. Ale twój punkt widzenia jest całkowicie słuszny w przypadku większości aplikacji renderujących 2D, które renderują na podstawie zdarzenia wejściowego na użytkownika.
ワ イ き ん ぐ
1
Asynchroniczne i nieblokujące to różne paradygmaty.
Markiz Lorne
73

Uważam, że główne rozróżnienie dotyczy współbieżności i równoległości .

Asynchroniczne i wywołania zwrotne są ogólnie sposobem (narzędziem lub mechanizmem) wyrażania współbieżności, tj. Zestawu jednostek, które mogą ze sobą rozmawiać i współdzielić zasoby. W przypadku asynchronii lub wywołania zwrotnego komunikacja jest niejawna, podczas gdy współdzielenie zasobów jest opcjonalne (rozważ RMI, gdzie wyniki są obliczane na zdalnej maszynie). Jak słusznie zauważono, zwykle robi się to z myślą o szybkości reakcji; nie czekać na zdarzenia o długim czasie oczekiwania .

Programowanie równoległe zwykle ma na celu przepustowość, podczas gdy opóźnienie, czyli czas zakończenia pojedynczego elementu, może być gorsze niż równoważny program sekwencyjny.

Aby lepiej zrozumieć różnicę między współbieżnością a równoległością, zacytuję z probabilistycznych modeli współbieżności Daniele Varacca, który jest dobrym zestawem uwag do teorii współbieżności:

Model obliczeń jest modelem współbieżności, kiedy jest w stanie przedstawić systemy jako złożone z niezależnych autonomicznych komponentów, prawdopodobnie komunikujących się ze sobą. Nie należy mylić pojęcia współbieżności z pojęciem równoległości. Obliczenia równoległe zwykle obejmują centralne sterowanie, które rozdziela pracę między kilka procesorów. Jednocześnie podkreślamy niezależność komponentów oraz fakt, że komunikują się one ze sobą. Równoległość jest jak starożytny Egipt, w którym faraon decyduje, a niewolnicy pracują. Współbieżność jest jak współczesne Włochy, gdzie każdy robi, co chce i wszyscy używają telefonów komórkowych.

Podsumowując , programowanie równoległe jest w pewnym sensie szczególnym przypadkiem współbieżności, w którym oddzielne jednostki współpracują w celu uzyskania wysokiej wydajności i przepływności (ogólnie).

Async i Callbacks to tylko mechanizm, który pozwala programiście wyrazić współbieżność. Weź pod uwagę, że dobrze znane wzorce projektowe programowania równoległego, takie jak wzorzec / proces roboczy lub mapowanie / zmniejszanie, są implementowane przez struktury, które używają mechanizmów niższego poziomu (asynchroniczne) do implementacji bardziej złożonych scentralizowanych interakcji.

igon
źródło
37

Ten artykuł bardzo dobrze to wyjaśnia: http://urda.cc/blog/2010/10/04/asynchronous-versus-parallel-programming

Chodzi o programowanie asynchroniczne:

Wywołania asynchroniczne służą do zapobiegania „blokowaniu” w aplikacji. [Takie] wywołanie przeniesie się do już istniejącego wątku (takiego jak wątek I / O) i wykona swoje zadanie, kiedy będzie to możliwe.

to o programowaniu równoległym:

W programowaniu równoległym nadal przerywasz pracę lub zadania, ale kluczową różnicą jest to, że uruchamiasz nowe wątki dla każdego kawałka pracy

i to w skrócie:

Asynchroniczne wywołania będą używać wątków już używanych przez system, a programowanie równoległe wymaga od programisty przerwania pracy, podkręcania i rozrywania potrzebnych wątków .

Paweł
źródło
3
Ten artykuł> wszystkie odpowiedzi tutaj (oprócz tego oczywiście!)
FellyTone84
1
Dzięki za link. Więc ... generalnie używaj wywołań asynchronicznych podczas komunikacji z interfejsu użytkownika do serwera (lub od klienta do usługi internetowej). Używaj równoległych wątków po stronie serwera lub usługi internetowej, a także w warstwie biznesowej.
goku_da_master
18

Moje podstawowe rozumienie to:

Programowanie asynchroniczne rozwiązuje problem oczekiwania na zakończenie kosztownej operacji, zanim będzie można zrobić cokolwiek innego. Jeśli możesz wykonać inne rzeczy, czekając na zakończenie operacji, to dobrze. Przykład: utrzymywanie uruchomionego interfejsu użytkownika podczas podróży i pobieranie większej ilości danych z usługi internetowej.

Programowanie równoległe jest powiązane, ale bardziej dotyczy dzielenia dużego zadania na mniejsze fragmenty, które można obliczyć w tym samym czasie. Wyniki z mniejszych fragmentów można następnie połączyć, aby uzyskać ogólny wynik. Przykład: śledzenie promieni, w którym kolor poszczególnych pikseli jest zasadniczo niezależny.

Prawdopodobnie jest to bardziej skomplikowane, ale myślę, że to podstawowa różnica.

Andrew Cooper
źródło
Jest to ładnie powiedziane, ale jest całkiem błędne. Podobnie jak asynchroniczność, równoległość umożliwia kontynuowanie przepływu sterowania bez czekania na zakończenie działań. Główna różnica polega na tym, że równoległość zależy od sprzętu.
serkan
13

Myślę o różnicy w tych kategoriach:

Asynchroniczny: odejdź i wykonaj to zadanie, a kiedy skończysz, wróć i powiedz mi i przynieś wyniki. W międzyczasie zajmę się innymi sprawami.

Równolegle: chcę, żebyś wykonał to zadanie. Jeśli to ułatwi, poproś kilku ludzi o pomoc. Jest to jednak pilne, więc poczekam tutaj, aż wrócisz z wynikami. Nic więcej nie mogę zrobić, dopóki nie wrócisz.

Oczywiście zadanie asynchroniczne może wykorzystywać równoległość, ale rozróżnienie - przynajmniej według mnie - polega na tym, czy zajmiesz się innymi rzeczami podczas wykonywania operacji, czy też całkowicie zatrzymasz wszystko, dopóki nie pojawią się wyniki.

Leonard H. Martin
źródło
13

async : Zrób to sam w innym miejscu i powiadom mnie o zakończeniu (oddzwonienie). Zanim będę mógł dalej robić swoje.

wprowadź opis obrazu tutaj

równolegle : Zatrudnij tylu facetów (wątków), ile chcesz i podziel pracę między nimi, aby zakończyć szybciej i daj mi znać (oddzwonienie), kiedy skończysz. Do tego czasu będę mógł dalej robić moje inne rzeczy.

wprowadź opis obrazu tutaj

główna różnica polega na tym, że równoległość zależy głównie od sprzętu.

serkan
źródło
11

To kwestia kolejności wykonania.

Jeśli A jest asynchroniczne z B, nie mogę z góry przewidzieć, kiedy części A będą miały miejsce w odniesieniu do części części B.

Jeśli A jest równoległe do B, to rzeczy w A dzieją się w tym samym czasie, co rzeczy w B. Jednakże kolejność wykonywania może nadal zostać zdefiniowana.

Być może trudność polega na tym, że słowo asynchroniczny jest niejednoznaczne.

Wykonuję asynchroniczne zadanie, kiedy każę lokajowi pobiec do sklepu po więcej wina i sera, a potem zapominam o nim i pracuję nad moją powieścią, aż ponownie zapuka do drzwi gabinetu. Równoległość ma miejsce tutaj, ale kamerdyner i ja jesteśmy zaangażowani w zasadniczo różne zadania i różne klasy społeczne, więc nie stosujemy tutaj tej etykiety.

Mój zespół pokojówek pracuje równolegle, gdy każda z nich myje inne okno.

Mój zespół wsparcia samochodu wyścigowego jest asynchronicznie równoległy, ponieważ każdy zespół pracuje na innej oponie i nie musi się ze sobą komunikować ani zarządzać wspólnymi zasobami podczas wykonywania swojej pracy.

Moja drużyna piłkarska (inaczej piłka nożna) pracuje równolegle, ponieważ każdy gracz niezależnie przetwarza informacje o boisku i porusza się po nim, ale nie są one w pełni asynchroniczne, ponieważ muszą komunikować się i reagować na komunikację innych.

Mój zespół marszowy jest również równoległy, ponieważ każdy z muzyków czyta muzykę i kontroluje swój instrument, ale są one wysoce synchroniczne: grają i maszerują w czasie do siebie nawzajem.

Działo gatlinga z krzywką można uznać za równoległe, ale wszystko jest w 100% synchroniczne, więc to tak, jakby jeden proces posuwał się naprzód.

Richard
źródło
9

Dlaczego asynchroniczne?

Ponieważ dzisiejsza aplikacja jest coraz bardziej połączona, a także potencjalnie długotrwałe zadania lub operacje blokujące, takie jak operacje we / wy sieci lub operacje na bazach danych, bardzo ważne jest, aby ukryć opóźnienia tych operacji, uruchamiając je w tle i wracając do interfejsu użytkownika. tak szybko jak to możliwe. Tutaj pojawia się asynchroniczny, responsywność .

Dlaczego programowanie równoległe?

Wraz ze wzrostem dzisiejszych zbiorów danych i coraz większą złożonością obliczeń. Dlatego bardzo ważne jest, aby skrócić czas wykonywania tych operacji związanych z procesorem, w tym przypadku, dzieląc obciążenie na porcje, a następnie wykonując je jednocześnie. Możemy to nazwać „równoległym”. Oczywiście zapewni to naszej aplikacji wysoką wydajność .

Code-EZ
źródło
5

Asynchroniczny Powiedzmy, że jesteś osobą kontaktową dla swojego klienta i musisz reagować, tj. Musisz udostępniać status, złożoność operacji, wymagane zasoby itp. Na każde pytanie. Teraz masz do wykonania czasochłonną operację i dlatego nie możesz tego podjąć, ponieważ musisz reagować na klienta 24 godziny na dobę, 7 dni w tygodniu. W związku z tym zlecasz czasochłonną operację komuś innemu, abyś mógł reagować. To jest asynchroniczne.

Programowanie równoległe Załóżmy, że masz zadanie do odczytania, powiedzmy, 100 linii z pliku tekstowego, a odczytanie jednej linii zajmuje 1 sekundę. W związku z tym przeczytanie pliku tekstowego zajmie 100 sekund. Teraz martwisz się, że klient musi czekać 100 sekund na zakończenie operacji. Dlatego tworzysz 9 kolejnych klonów i każesz każdemu z nich wczytywać 10 wierszy z pliku tekstowego. Teraz odczytanie 100 wierszy zajmuje tylko 10 sekund. Dzięki temu masz lepszą wydajność.

Podsumowując, kodowanie asynchroniczne jest wykonywane w celu uzyskania responsywności, a programowanie równoległe odbywa się w celu uzyskania wydajności.

Varun Shridhar
źródło
4

Asynchroniczne: uruchamianie metody lub zadania w tle bez blokowania. Może niekoniecznie działać na osobnym wątku. Wykorzystuje przełączanie kontekstu / planowanie czasu.

Zadania równoległe: każde zadanie jest uruchamiane równolegle. Nie używa przełączania kontekstu / planowania czasu.

Aditya Bokade
źródło
4

Przyjechałem tutaj dość dobrze z tymi dwoma koncepcjami, ale z czymś nie do końca jasnym na ich temat.

Po przeczytaniu niektórych odpowiedzi myślę, że mam poprawną i pomocną metaforę do opisania różnicy.

Jeśli myślisz o swoich indywidualnych liniach kodu jako o oddzielnych, ale uporządkowanych kartach do gry (zatrzymaj mnie, jeśli wyjaśnię, jak działają oldschoolowe karty ponczowe), to dla każdej oddzielnej procedury będziesz mieć unikalny stos kart (nie kopiuj i wklej!), a różnica między tym, co normalnie dzieje się, gdy kod jest uruchamiany normalnie i asynchronicznie, zależy od tego, czy Ci zależy, czy nie.

Kiedy uruchamiasz kod, przekazujesz systemowi operacyjnemu zestaw pojedynczych operacji (na które Twój kompilator lub interpreter złamał twój kod „wyższego” poziomu), które mają być przekazane do procesora. W przypadku jednego procesora w danym momencie można wykonać tylko jedną linię kodu. Tak więc, aby uzyskać iluzję uruchamiania wielu procesów w tym samym czasie, system operacyjny wykorzystuje technikę, w której wysyła procesorowi tylko kilka wierszy z danego procesu na raz, przełączając się między wszystkimi procesami zgodnie z tym, jak widzi dopasowanie. Rezultatem jest wiele procesów pokazujących postęp użytkownikowi końcowemu w tym samym czasie.

Według naszej metafory związek jest taki, że system operacyjny zawsze tasuje karty przed wysłaniem ich do procesora. Jeśli twój stos kart nie zależy od innego stosu, nie zauważysz, że twój stos przestał być wybierany, gdy inny stos stał się aktywny. Więc jeśli cię to nie obchodzi, to nie ma znaczenia.

Jeśli jednak Cię to obchodzi (np. Istnieje wiele procesów - lub stosy kart - które są od siebie zależne), tasowanie systemu operacyjnego zepsuje wyniki.

Pisanie kodu asynchronicznego wymaga obsługi zależności między kolejnością wykonywania, niezależnie od tego, czym skończy się ta kolejność. Właśnie dlatego używane są konstrukcje takie jak „call-backs”. Mówią do procesora: „Następną rzeczą do zrobienia jest poinformowanie drugiego stosu, co zrobiliśmy”. Korzystając z takich narzędzi, można mieć pewność, że drugi stos zostanie powiadomiony, zanim zezwoli systemowi operacyjnemu na wykonanie dalszych instrukcji. („If named_back == false: send (no_operation)” - nie jestem pewien, czy tak jest faktycznie zaimplementowane, ale logicznie myślę, że jest to spójne.)

W przypadku procesów równoległych różnica polega na tym, że masz dwa stosy, które nie dbają o siebie nawzajem, oraz dwóch pracowników przetwarzających je. Pod koniec dnia może być konieczne połączenie wyników z dwóch stosów, co byłoby wówczas kwestią synchronizacji, ale w przypadku wykonania znowu nie obchodzi cię to.

Nie jestem pewien, czy to pomaga, ale zawsze uważam, że wiele wyjaśnień jest pomocnych. Należy również zauważyć, że wykonywanie asynchroniczne nie jest ograniczone do pojedynczego komputera i jego procesorów. Ogólnie rzecz biorąc, dotyczy czasu lub (jeszcze bardziej ogólnie) kolejności wydarzeń. Jeśli więc wyślesz zależny stos A do węzła sieciowego X i jego sprzężony stos B do Y, prawidłowy kod asynchroniczny powinien być w stanie uwzględnić sytuację, tak jakby działał lokalnie na twoim laptopie.

philrea
źródło
2

Ogólnie rzecz biorąc, są tylko dwa sposoby, aby za każdym razem zrobić więcej niż jedną rzecz. Jedna jest asynchroniczna , druga jest równoległa .

Z wysokiego poziomu, jak popularny serwer NGINX i słynna biblioteka Python Tornado , oba w pełni wykorzystują asynchroniczny paradygmat, który polega na tym, że serwer jednowątkowy może jednocześnie obsługiwać tysiące klientów (niektóre IOloop i wywołania zwrotne ). Korzystanie z metody ECF (po kontroli wyjątków), która może zaimplementować paradygmat programowania asynchronicznego. więc asynchroniczność czasami nie robi rzeczy jednocześnie, ale niektóre operacje związane z io, asynchroniczne mogą naprawdę promować wydajność.

Równolegle paradygmat zawsze odnosi wielu wątków i wieloprocesorowe. Może to w pełni wykorzystywać wielordzeniowe procesory i robić rzeczy naprawdę jednocześnie.

ideoutrea
źródło
-1

Podsumowanie wszystkich powyższych odpowiedzi

  1. Równoległe obliczenia:

▪ rozwiązuje problem z przepustowością. Troszczy się o podzielenie dużego zadania na mniejsze kawałki

▪ jest związany z maszyną (potrzeba wielu maszyn / rdzeni / procesorów / procesorów), np.: Master slave, zmniejszanie mapy.

Obliczenia równoległe zwykle obejmują centralne sterowanie, które rozdziela pracę między kilka procesorów

  1. asynchroniczny:

▪ rozwiązuje problem z opóźnieniami, tj. Problem „czekania” na zakończenie kosztownej operacji, zanim będziesz mógł zrobić cokolwiek innego

▪ jest powiązany z wątkami (potrzeba wielu wątków)

Wątkowanie (przy użyciu Thread, Runnable, Executor) jest jednym z podstawowych sposobów wykonywania operacji asynchronicznych w Javie

Vyshnav Ramesh Thrissur
źródło