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.
multithreading
asynchronous
parallel-processing
Matt Sherman
źródło
źródło
Odpowiedzi:
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.
źródło
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:
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.
źródło
Ten artykuł bardzo dobrze to wyjaśnia: http://urda.cc/blog/2010/10/04/asynchronous-versus-parallel-programming
Chodzi o programowanie asynchroniczne:
to o programowaniu równoległym:
i to w skrócie:
źródło
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.
źródło
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.
źródło
async : Zrób to sam w innym miejscu i powiadom mnie o zakończeniu (oddzwonienie). Zanim będę mógł dalej robić swoje.
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.
główna różnica polega na tym, że równoległość zależy głównie od sprzętu.
źródło
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.
źródło
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ść .
źródło
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.
źródło
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.
źródło
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.
źródło
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.
źródło
Podsumowanie wszystkich powyższych odpowiedzi
▪ 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
▪ 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
źródło