Jak ważny jest wielowątkowość w obecnej branży oprogramowania? [Zamknięte]


59

Mam prawie 3 lata doświadczenia w pisaniu aplikacji internetowych w Javie przy użyciu frameworków MVC (takich jak struts). Do tej pory nie pisałem kodu wielowątkowego, chociaż napisałem kod dla dużych sieci handlowych.

Podczas wywiadów otrzymuję kilka pytań na temat wielowątkowości i zwykle odpowiadam na nie (głównie proste pytania). To mnie zastanawia, jak ważna jest wielowątkowość w obecnym scenariuszu branżowym?


8
Być może nie zrobiłeś tego wprost, ale zdecydowanie wykorzystałeś to za kulisami.
Martin York,

1
Zbyt rzadko pracuję z wielowątkowym kodem do pracy, ale staram się go czytać / rozmawiać o nim podczas wywiadu. Nie chciałbym pracować z programistami, którzy nie otrzymują wątków, i nie chciałbym pracować z programistami, którzy nie dbają o to, czy inni koderzy otrzymają wątki.
Job

1
Rzadko używam go do tworzenia stron internetowych, ale myślę, że jest bardziej powszechny gdzie indziej. Na przykład, byłem niedawno pisząc aplikację na Androida i realizowany jesteś zobowiązany do korzystania wielowątkowość, jeśli masz jakiekolwiek aktywności sieciowej.
jwegner,

4
To nie wielowątkowość jest ważna, to przetwarzanie równoległe. Jeśli uważasz, że wszystko, co dotyczy twojej aplikacji internetowej, jest w wątku ... musisz coś palić.
user606723,

1
Możliwość „myślenia poza wątkiem” jest bardzo przyjemna nawet w przypadku programowania jednowątkowego. Przyjmujesz o wiele mniej za pewnik, a Twój kod jest ogólnie bardziej niezawodny i można go ponownie wykorzystać.
corsiKa,

Odpowiedzi:


92

To jest bardzo ważne.

Ważniejsze jest jednak zrozumienie, że wielowątkowość jest tylko jednym ze sposobów rozwiązania problemu asynchronicznego. Środowisko techniczne, w którym wiele osób pisze teraz oprogramowanie, różni się od historycznego środowiska programistycznego (monolitycznych aplikacji wykonujących obliczenia wsadowe) na dwa kluczowe sposoby:

  • Maszyny wielordzeniowe są teraz powszechne. Nie możemy już oczekiwać, że prędkości zegara lub gęstości tranzystorów wzrosną o rzędy wielkości. Cena obliczeń będzie nadal spadać, ale spadnie z powodu dużej równoległości. Będziemy musieli znaleźć sposób na wykorzystanie tej mocy.

  • Komputery są teraz silnie połączone w sieć, a nowoczesne aplikacje polegają na możliwości pobierania bogatych informacji z różnych źródeł.

Z obliczeniowego punktu widzenia te dwa czynniki sprowadzają się zasadniczo do tej samej podstawowej idei: informacje będą coraz częściej dostępne w sposób asynchroniczny . To, czy potrzebne informacje są obliczane na innym chipie w komputerze, czy na chipie w połowie świata, nie ma znaczenia. Tak czy inaczej, twój procesor siedzi tam i pali miliardy cykli na sekundę, czekając na informacje, kiedy może wykonywać pożyteczną pracę.

Tak więc to, co ma znaczenie teraz, a co będzie jeszcze ważniejsze w przyszłości, to nie wielowątkowość per se, ale raczej radzenie sobie z asynchronią . Wielowątkowość to tylko jeden ze sposobów - skomplikowany, podatny na błędy sposób, który stanie się jeszcze bardziej skomplikowany i podatny na błędy w miarę, jak coraz częściej stosowane będą układy o słabej pamięci.

Wyzwaniem dla dostawców narzędzi jest wymyślenie czegoś lepszego niż wielowątkowość dla naszych klientów, aby poradzić sobie z infrastrukturą asynchroniczną, z której będą korzystać w przyszłości.


5
+1 za doskonałą odpowiedź, zasługuje na więcej uznania niż moja skromna próba.
Péter Török,

2
Informacje będą coraz częściej dostępne w sposób asynchroniczny. Jeśli to nie jest prawda. . .
surfasb,

2
concurrencyjest ważniejsze niż asynchronous zachowanie. Możesz mieć asynchroniczny bez współbieżności (tj. Wiele wątków na jednym rdzeniu procesora) asynchronousnie jest semantycznym substytutem concurrency.

5
@Jarrod: Oswajanie asynchrony jest bardziej istotne niż tylko oswajania współbieżność dla właśnie powód, można wymienić: współbieżności jest właśnie szczególnie trudny rodzaj asynchrony. Trudną częścią współbieżności nie jest aspekt „rzeczy dziejące się w tym samym czasie” i rzeczywiście współbieżność jest często symulowaną współbieżnością , np. Niewspółpracującą wielozadaniowością poprzez podział czasu. Trudność polega na wydajnym korzystaniu z zasobów bez blokowania, zawieszania się, zakleszczania i bez pisania na wylot programów trudnych do uzasadnienia na poziomie lokalnym.
Eric Lippert,

„współbieżność jest często tylko symulowaną współbieżnością, np. niewspółpracującą wielozadaniowością poprzez podział czasu”: w moim rozumieniu jest to nadal (prawdziwa) współbieżność, może masz na myśli, że nie jest to równoległość?
Giorgio

46

Jest to coraz ważniejsze, ponieważ nowoczesne procesory mają coraz więcej rdzeni. Dziesięć lat temu większość istniejących komputerów miała tylko jeden procesor, dlatego wielowątkowość była ważna tylko w aplikacjach serwerowych wyższej klasy. Obecnie nawet podstawowe laptopy mają procesory wielordzeniowe. Za kilka lat nawet urządzenia mobilne ... Tak więc potrzeba coraz więcej kodu, aby wykorzystać potencjalne zalety współbieżności i działać poprawnie w środowisku wielowątkowym.


3
+1: ważniejsze niż kiedykolwiek. Pamiętaj też, że przy projektowaniu systemu możesz także czerpać korzyści z wielowątkowości, dzieląc pracę na partycje, tak aby robiło to więcej procesów.
Scott C Wilson,

11
Sporo urządzeń mobilnych ma już procesory wielordzeniowe!
Che Jami,

3
Twierdziłbym, że wielowątkowość jest ważna od czasu zbudowania pierwszego systemu współdzielenia czasu. Posiadanie wielu procesorów / rdzeni dodaje nowy wymiar wydajności do posiadania wielu wątków.
jwernerny

Być może (szczególnie na urządzeniach mobilnych) wątki to zły pomysł. System operacyjny powinien prawdopodobnie obsługiwać optymalizację wykorzystania rdzeni bez błędnego kodu użytkownika próbującego wykonywać wątki. Jest bardzo niewiele aplikacji, które normalny użytkownik ma dostęp do tej potrzeby lub byłoby korzystne dla wielu osób. Jedynym wyjątkiem są (wysokiej klasy aplikacje graficzne / narzędzia dla programistów / modelowanie pogody / serwery sieciowe (i powiązane usługi)) wszystkie bardzo zaawansowane aplikacje specjalistyczne.
Martin York,

1
@ Tux-D, możesz mieć grę na urządzeniu mobilnym, która wykorzystuje więcej niż jeden rdzeń. To nie jest coś wyjątkowego.
whitequark,

28

Ogólnie rzecz biorąc, wielowątkowość jest już dość ważna i będzie coraz ważniejsza w ciągu następnych kilku lat (jak zauważył Péter Török) - w ten sposób procesory będą skalowane w przewidywalnej przyszłości (więcej rdzeni zamiast wyższych MHz) .

W twoim przypadku jednak wydaje się, że pracujesz głównie z aplikacjami internetowymi. Aplikacje internetowe ze swej natury są wielowątkowe ze względu na sposób, w jaki serwer WWW przetwarza żądania dla każdego użytkownika (tj. Równolegle). Chociaż prawdopodobnie ważne jest, aby zrozumieć współbieżność i bezpieczeństwo wątków (szczególnie w przypadku pamięci podręcznych i innych współdzielonych danych), wątpię, aby natknąć się na zbyt wiele przypadków, w których korzystne jest wielowątkowy kod aplikacji internetowej (np. Wielu pracowników wątki na żądanie). W tym sensie uważam, że bycie ekspertem w wielowątkowości nie jest tak naprawdę konieczne dla programisty. Często jest zadawany w wywiadach, ponieważ jest to dość trudny temat, a także dlatego, że wielu ankieterów po prostu wyszukuje w Google kilka pytań na 10 minut przed przyjazdem.


+1 za notatkę, że plakat jest programistą stron internetowych i większość kontenerów serwerów WWW wykonuje dla Ciebie przyzwoitą pracę wielowątkową. W niektórych przypadkach nie eliminuje to potrzeby, ale 99% czasu kodu kontrolera wielowątkowego nie jest największą poprawą wydajności wywołania MVC.
Mufasa,

19

Wielowątkowość to czerwony śledź. Wielowątkowość to szczegół implementacji rzeczywistego problemu, jakim jest współbieżność . Nie wszystkie programy wątkowe są współbieżne z powodu blokad, a co nie.

Wątki to tylko jeden model i wzorzec implementacji dla concurrentprogramów wdrażających .

Na przykład możesz napisać wysoce skalowalne i odporne na błędy oprogramowanie bez konieczności wykonywania wielu wątków w językach takich jak Erlang.


+1, chociaż nadal uważam, że Erlang jest wielowątkowy; społeczność właśnie przedefiniowała słowo „wątek”, tak aby zależało od zmiennego stanu wspólnego, a tym samym odróżniało się od niego.
Dan

1
maszyna wirtualna Erlang wykorzystuje domyślnie 1 wątek na procesor, ale jako programista Erlang nie masz dostępu do podstawowych wątków systemu operacyjnego, tylko lekkie procesy dostarczane przez maszynę Erlang.

10

Podczas wywiadów otrzymuję kilka pytań na temat wielowątkowości ...

Cóż, jeśli chodzi o przekazywanie wywiadów, wielowątkowość może być bardzo ważna. Cytując siebie : „podczas przeprowadzania wywiadów z kandydatami do naszego zespołu zadaję pytania dotyczące współbieżności nie dlatego, że umiejętności te są ważne w naszym projekcie ( nie są ), ale ponieważ w jakiś sposób ułatwiają mi ocenę ogólnej znajomości używanego przez nas języka ...”


2
Pomysł na temat wielowątkowości i programowania współbieżnego zwykle przekłada się na podejście obronne, co może być bardzo dobre. Jeśli musisz wziąć pod uwagę, że coś całkowicie niezwiązanego z twoim procesem może, ale nie musi, zapobiegać pojedynczej instrukcji logicznej i wykonać w środku wszystkiego innego, musisz zaplanować taką możliwość. Implementacje wielowątkowe (w przeciwieństwie do innych form współbieżności) po prostu oznaczają, że masz dodatkowe obciążenie, ponieważ może to zrobić coś dla dowolnego stanu, który nie jest lokalny dla wątków.
CVn

6

Zrozumienie, w jaki sposób wykorzystać wątkowanie do poprawy wydajności, jest kluczową umiejętnością w dzisiejszym środowisku oprogramowania dla większości branż i aplikacji.

Przynajmniej zrozumienie problemów związanych z współbieżnością powinno być pewne.

Oczywista uwaga, że ​​nie wszystkie aplikacje lub środowiska będą mogły z niej skorzystać, dotyczy to na przykład wielu systemów wbudowanych. Wydaje się jednak, że procesor Atom (i wsp.) Wydaje się działać na rzecz zmiany tego (lekki multoreaktor zaczyna być coraz bardziej powszechny).


4

Wygląda na to, że piszesz już kod wielowątkowy.

Większość aplikacji internetowych Java może obsługiwać wiele żądań jednocześnie i robi to przy użyciu wielu wątków.

Dlatego powiedziałbym, że ważne jest, aby znać przynajmniej podstawy.


18
<nitpick> najwyraźniej nie pisze kodu wielowątkowego, tylko kod (jednowątkowy), który jest uruchamiany w środowisku wielowątkowym. </nitpick>
Péter Török

2

Jest to nadal ważne w sytuacjach, gdy jest to potrzebne, ale podobnie jak wiele rzeczy w fazie rozwoju, jest to właściwe narzędzie do właściwej pracy. Byłem przez 3 lata bez dotykania wątków, teraz praktycznie wszystko, co robię, ma w tym jakieś podstawy. W przypadku procesorów wielordzeniowych nadal istnieje wielka potrzeba wątkowania, ale wszystkie tradycyjne powody są nadal aktualne, nadal potrzebujesz responsywnych interfejsów i nadal możesz być w stanie poradzić sobie z synchronizacją i zająć się innymi rzeczami jednocześnie.


2

Krótka odpowiedź: bardzo.

Dłuższa odpowiedź: komputery elektroniczne (oparte na tranzystorach) szybko zbliżają się do fizycznych ograniczeń technologii. Coraz trudniej jest wyciskać więcej zegarów z każdego rdzenia, jednocześnie zarządzając wytwarzaniem ciepła i efektami kwantowymi obwodów mikroskopowych (ścieżki obwodów są już tak blisko siebie na nowoczesnych układach scalonych, że efekt zwany „tunelowaniem kwantowym” może wytworzyć elektron „przeskakiwać tory” z jednego obwodu do drugiego, bez potrzeby posiadania odpowiednich warunków dla tradycyjnego łuku elektrycznego); tak więc praktycznie wszyscy producenci układów skupiają się na tym, aby każdy zegar był w stanie zrobić więcej, umieszczając więcej „jednostek wykonawczych” w każdym procesorze. Następnie zamiast komputera wykonującego tylko jedną czynność na zegar, może wykonać 2, 4, a nawet 8. Intel ma funkcję „HyperThreading”, który w zasadzie dzieli jeden rdzeń procesora na dwa logiczne procesory (z pewnymi ograniczeniami). Praktycznie wszyscy producenci umieszczają co najmniej dwa oddzielne rdzenie procesora w jednym układzie CPU, a obecny złoty standard dla procesorów stacjonarnych to cztery rdzenie na układ. Osiem jest możliwe, gdy używane są dwa układy CPU, istnieją płyty główne serwera zaprojektowane dla procesorów „czterordzeniowych” (16 EU plus opcjonalny HT), a kolejna generacja procesorów prawdopodobnie będzie miała sześć lub osiem na układ.

Konsekwencją tego wszystkiego jest to, że aby w pełni wykorzystać sposób, w jaki komputery zyskują moc obliczeniową, musisz być w stanie pozwolić komputerowi na „podzielenie się i podbicie” twojego programu. Języki zarządzane mają co najmniej wątek GC, który obsługuje zarządzanie pamięcią niezależnie od programu. Niektóre mają również wątki „przejściowe”, które obsługują współdziałanie COM / OLE (tyle samo do ochrony zarządzanego „piaskownicy”, co do wydajności). Poza tym jednak naprawdę musisz zacząć myśleć o tym, jak twój program może wykonywać wiele rzeczy jednocześnie, i zaprojektować swój program za pomocą funkcji zaprojektowanych tak, aby umożliwić asynchroniczną obsługę części programu. Windows i użytkownicy Windows praktycznie oczekują, że Twój program wykona długie, skomplikowane zadania w wątkach w tle, które utrzymują interfejs użytkownika programu (który działa w głównym wątku programu) „reagując” na pętlę komunikatów systemu Windows. Oczywiście problemy, które mają równoległe rozwiązania (takie jak sortowanie) są naturalnymi kandydatami, ale istnieje skończona liczba rodzajów problemów, które korzystają z równoległości.


1

Tylko ostrzeżenie o wielowątkowości: więcej wątków nie oznacza lepszej wydajności. Jeśli nie będzie właściwie zarządzany, mogą spowolnić system. Aktor Scali ulepsza wątki Javy i maksymalizuje wykorzystanie systemu (wspomniał o tym jako programista Java).

EDYCJA: Oto kilka rzeczy, o których należy pamiętać na temat wad wielowątkowości:

  • interferencja wątków ze sobą podczas udostępniania zasobów sprzętowych
  • Czasy wykonania pojedynczego wątku nie ulegają poprawie, ale mogą zostać obniżone, nawet gdy wykonywany jest tylko jeden wątek. Jest to spowodowane wolniejszymi częstotliwościami i / lub dodatkowymi etapami rurociągu, które są niezbędne do dostosowania sprzętu do przełączania wątków.
  • Sprzętowa obsługa wielowątkowości jest bardziej widoczna dla oprogramowania, dlatego wymaga więcej zmian zarówno w aplikacjach, jak i systemach operacyjnych niż w przypadku wieloprocesowego.
  • Trudność zarządzania współbieżnością.
  • Trudność testowania.

Również ten link może pomóc w tym samym.


2
To nie wydaje się odpowiadać na pytanie PO: - /
Péter Török,

Daje to jednak widok wątków na najwyższym (najbardziej) poziomie. Należy rozważyć przed przystąpieniem do wielowątkowości.
c0da,

@ c0da Stack Exchange nie jest forum dyskusyjnym: odpowiedzi powinny bezpośrednio odpowiadać na pytanie. Czy potrafisz rozszerzyć swoją odpowiedź, aby przywrócić ją do tego, czego szuka pytający?

1

To mnie zastanawia, jak ważna jest wielowątkowość w obecnym scenariuszu branżowym?

W obszarach krytycznych pod względem wydajności, w których wydajność nie pochodzi od kodu innej firmy wykonującego ciężkie prace, ale naszego własnego, to zwykle rozważam rzeczy w tej kolejności ważności z punktu widzenia procesora (GPU to symbol wieloznaczny, który wygrałem nie wchodzi):

  1. Wydajność pamięci (np .: lokalizacja odniesienia).
  2. Algorytmiczne
  3. Wielowątkowość
  4. SIMD
  5. Inne optymalizacje (wskazówki dotyczące przewidywania gałęzi statycznych, np.)

Należy pamiętać, że ta lista nie opiera się wyłącznie na znaczeniu, ale na wielu innych dynamikach, takich jak wpływ, jaki mają one na utrzymanie, jak proste są (jeśli nie, warto rozważyć je wcześniej), ich interakcje z innymi na liście itp.

Wydajność pamięci

Najbardziej może dziwić mój wybór wydajności pamięci w porównaniu z algorytmem. Wynika to z faktu, że wydajność pamięci współdziała ze wszystkimi 4 innymi pozycjami na tej liście, i dlatego, że rozpatrywanie jej często dotyczy kategorii „projektowanie”, a nie „implementacji”. Jest co prawda trochę problemu z kurczakiem lub jajkiem, ponieważ zrozumienie wydajności pamięci często wymaga uwzględnienia wszystkich 4 pozycji na liście, podczas gdy wszystkie 4 inne pozycje również wymagają rozważenia wydajności pamięci. Ale to jest sedno wszystkiego.

Na przykład, jeśli potrzebujemy struktury danych, która oferuje sekwencyjny dostęp w czasie liniowym i wstawianie w czasie stałym z tyłu i nic więcej dla małych elementów, naiwnym wyborem, do którego należy sięgnąć, byłaby połączona lista. Pomija to wydajność pamięci. Jeśli weźmiemy pod uwagę wydajność pamięci w miksie, to ostatecznie wybieramy bardziej ciągłe struktury w tym scenariuszu, takie jak rozwijalne struktury oparte na macierzy lub bardziej ciągłe węzły (np. Jeden przechowujący 128 elementów w węźle) połączone ze sobą, a przynajmniej połączona lista wspierana przez alokator puli. Mają one dramatyczną przewagę, mimo że mają tę samą złożoność algorytmiczną. Podobnie często wybieramy szybkie sortowanie tablicy zamiast sortowania scalonego pomimo mniejszej złożoności algorytmicznej po prostu ze względu na wydajność pamięci.

Podobnie, nie możemy mieć wydajnego wielowątkowości, jeśli nasze wzorce dostępu do pamięci są tak szczegółowe i rozproszone, że w rezultacie maksymalizujemy ilość fałszywego udostępniania, jednocześnie blokując na najbardziej szczegółowych poziomach w kodzie. Tak więc wydajność pamięci zwielokrotnia wydajność wielowątkowości. Jest to warunek wstępny, aby jak najlepiej wykorzystać wątki.

Każda pozycja powyżej na liście ma złożoną interakcję z danymi, a skupienie się na tym, jak dane są reprezentowane, zależy ostatecznie od wydajności pamięci. Każde z powyższych może być utrudnione przez niewłaściwy sposób reprezentowania lub dostępu do danych.

Innym powodem jest to, sprawność pamięci, więc ważne jest, że można go zastosować w całej całym kodzie. Zasadniczo, gdy ludzie wyobrażają sobie, że nieefektywność kumuluje się z niewielkimi fragmentami pracy tu i tam, jest to znak, że muszą pobrać profiler. Jednak pola o niskim opóźnieniu lub te, które mają do czynienia z bardzo ograniczonym sprzętem, w rzeczywistości znajdą, nawet po profilowaniu, sesje, które wskazują brak wyraźnych punktów aktywnych (tylko czasami rozproszone po całym miejscu) w bazie kodu, która jest rażąco nieefektywna w sposobie przydzielania, kopiowania i dostęp do pamięci. Zazwyczaj jest to jedyny raz, kiedy cała baza kodu może być podatna na problemy z wydajnością, które mogą prowadzić do zastosowania zupełnie nowego zestawu standardów w całej bazie kodu, a wydajność pamięci jest często jej istotą.

Algorytmiczne

Ten jest dość oczywisty, ponieważ wybór w algorytmie sortowania może zrobić różnicę między ogromnym wejściem zajmującym miesiące sortowania a sekundami sortowania. Ma największy wpływ ze wszystkich, jeśli wybór jest między, powiedzmy, naprawdę słabo rozwiniętymi algorytmami kwadratowymi lub sześciennymi a algorytmem liniowo-rytmicznym, lub między liniowym a logarytmicznym lub stałym, przynajmniej do czasu, aż uzyskamy około 1 000 000 podstawowych maszyn (w tym przypadku pamięć wydajność stałaby się jeszcze ważniejsza).

Nie znajduje się jednak na szczycie mojej osobistej listy, ponieważ każdy kompetentny w swojej dziedzinie znałby strukturę przyspieszania w celu eliminacji frustum, np. Jesteśmy nasyceni wiedzą algorytmiczną i znamy takie rzeczy, jak używanie wariantu trie, takiego jak drzewo radix dla wyszukiwań opartych na prefiksach to rzeczy dla dzieci. Brak takiej podstawowej wiedzy na temat dziedziny, w której pracujemy, sprawiłby, że wydajność algorytmiczna z pewnością wzniosłaby się na szczyt, ale często wydajność algorytmiczna jest banalna.

Również wynalezienie nowych algorytmów może być koniecznością w niektórych dziedzinach (np. W przetwarzaniu siatki musiałem wymyślić setki, ponieważ albo wcześniej nie istniały, albo implementacje podobnych funkcji w innych produktach były zastrzeżonymi tajemnicami, nie opublikowanymi w pracy ). Jednak gdy miniemy część dotyczącą rozwiązywania problemów i znajdziemy sposób na uzyskanie prawidłowych wyników, a gdy efektywność stanie się celem, jedynym sposobem na osiągnięcie tego jest zastanowienie się, w jaki sposób wchodzimy w interakcję z danymi (pamięcią). Bez zrozumienia wydajności pamięci nowy algorytm może stać się niepotrzebnie złożony dzięki daremnym wysiłkom, aby przyspieszyć go, gdy jedyną rzeczą, której potrzebował, było nieco większe rozważenie wydajności pamięci w celu uzyskania prostszego, bardziej eleganckiego algorytmu.

Wreszcie, algorytmy są bardziej w kategorii „implementacja” niż wydajność pamięci. Często są łatwiejsze do poprawienia z perspektywy czasu, nawet przy początkowo nieoptymalnym algorytmie. Na przykład gorszy algorytm przetwarzania obrazu jest często implementowany tylko w jednym lokalnym miejscu w bazie kodu. Później można go wymienić na lepszy. Jeśli jednak wszystkie algorytmy przetwarzania obrazu są powiązane z Pixelinterfejsem, który ma nieoptymalną reprezentację pamięci, ale jedynym sposobem na poprawienie tego jest zmiana sposobu reprezentacji wielu pikseli (a nie jednego), wtedy często jesteśmy SOL i będzie musiał całkowicie przepisać bazę kodu w kierunkuImageberło. To samo dotyczy zastąpienia algorytmu sortowania - zwykle jest to szczegół implementacji, podczas gdy pełna zmiana podstawowej reprezentacji sortowanych danych lub sposobu ich przesyłania przez wiadomości może wymagać przeprojektowania interfejsów.

Wielowątkowość

Wielowątkowość jest trudna w kontekście wydajności, ponieważ jest to optymalizacja na poziomie mikro, grająca według cech sprzętowych, ale nasz sprzęt naprawdę skaluje się w tym kierunku. Już mam rówieśników, którzy mają 32 rdzenie (mam tylko 4).

Jednak wielowątkowość jest jedną z najniebezpieczniejszych mikrooptymalizacji prawdopodobnie znanych profesjonalistom, jeśli celem jest przyspieszenie oprogramowania. Stan wyścigu jest najbardziej zabójczym możliwym błędem, ponieważ ma tak nieokreślony charakter (być może pojawia się tylko raz na kilka miesięcy na maszynie programisty w najbardziej niewygodnym momencie poza kontekstem debugowania, jeśli w ogóle). Ma więc prawdopodobnie najbardziej negatywny wpływ na łatwość konserwacji i potencjalną poprawność kodu spośród nich wszystkich, zwłaszcza, że ​​błędy związane z wielowątkowością mogą łatwo latać pod radarem nawet najbardziej dokładnych testów.

Niemniej jednak staje się to bardzo ważne. Chociaż wciąż nie zawsze może to przebijać wydajność pamięci (co czasami może przyspieszać sto razy szybciej), biorąc pod uwagę liczbę rdzeni, które mamy teraz, widzimy coraz więcej rdzeni. Oczywiście nawet w przypadku 100-rdzeniowych maszyn nadal umieszczam wydajność pamięci na szczycie listy, ponieważ bez niej wydajność wątków jest na ogół niemożliwa. Program może korzystać ze stu wątków na takiej maszynie i nadal jest powolny bez wydajnej reprezentacji pamięci i wzorców dostępu (które wiążą się z wzorcami blokującymi).

SIMD

SIMD jest również trochę niewygodny, ponieważ rejestry stają się coraz szersze, a plany są jeszcze szersze. Początkowo widzieliśmy 64-bitowe rejestry MMX, a następnie 128-bitowe rejestry XMM zdolne do 4 równoległych operacji SPFP. Teraz widzimy 256-bitowe rejestry YMM zdolne do 8 równolegle. Istnieją już plany dotyczące rejestrów 512-bitowych, które pozwoliłyby na 16 równolegle.

Będą one oddziaływać i rozmnażać się przy wydajności wielowątkowości. Jednak SIMD może obniżyć łatwość konserwacji tak samo, jak wielowątkowość. Chociaż związane z nimi błędy niekoniecznie są tak trudne do odtworzenia i naprawienia jak impas lub warunki wyścigu, przenośność jest niewygodna, a zapewnienie, że kod może działać na wszystkich komputerach (i przy użyciu odpowiednich instrukcji opartych na ich możliwościach sprzętowych) jest niezręczny.

Inną rzeczą jest to, że chociaż dzisiejsze kompilatory zwykle nie pobijają fachowo napisanego kodu SIMD, łatwo pokonują naiwne próby. Mogą poprawić się do tego stopnia, że ​​nie musimy już robić tego ręcznie, a przynajmniej nie stać się tak ręcznym, aby pisać wewnętrzne instrukcje lub prosty kod asemblera (być może po prostu trochę ludzkiego przewodnika).

Ponownie jednak bez układu pamięci wydajnego do przetwarzania wektoryzacyjnego karta SIMD jest bezużyteczna. W końcu załadujemy jedno pole skalarne do szerokiego rejestru, aby wykonać tylko jedną operację. Istotą wszystkich tych elementów jest zależność od układów pamięci, aby była naprawdę wydajna.

Inne optymalizacje

Często sugeruję, abyśmy zaczęli nazywać je teraz „mikro”, jeśli słowo to sugeruje nie tylko wyjście poza skupienie się na algorytmie, ale także na zmiany, które mają niewielki wpływ na wydajność.

Często próba optymalizacji pod kątem przewidywania gałęzi wymaga zmiany algorytmu lub wydajności pamięci, np. Jeśli spróbuje się tego jedynie poprzez podpowiedzi i przestawienie kodu w celu przewidywania statycznego, poprawia to tylko wykonanie pierwszego kodu po raz pierwszy, co powoduje, że efekty są wątpliwe, jeśli często nieistotny.

Powrót do wielowątkowości dla wydajności

W każdym razie, jak ważna jest wielowątkowość w kontekście wydajności? Na mojej 4-rdzeniowej maszynie idealnie może zrobić to około 5 razy szybciej (co mogę uzyskać dzięki hyperthreading). Byłoby to znacznie ważniejsze dla mojego kolegi, który ma 32 rdzenie. I będzie coraz ważniejsze w nadchodzących latach.

To bardzo ważne. Ale nie ma sensu po prostu rzucać wiązką wątków na problem, jeśli nie ma wydajności pamięci, aby pozwolić na oszczędne używanie blokad, aby zmniejszyć fałszywe udostępnianie itp.

Wielowątkowość poza wydajnością

Wielowątkowość nie zawsze polega na czystej wydajności w sensie bezpośredniej przepustowości. Czasami służy do równoważenia obciążenia nawet przy możliwym koszcie przepustowości, aby poprawić reakcję na użytkownika lub pozwolić użytkownikowi wykonać więcej zadań wielozadaniowych bez czekania na zakończenie (np. Kontynuuj przeglądanie podczas pobierania pliku).

W takich przypadkach sugerowałbym, że wielowątkowość rośnie jeszcze wyżej w górę (być może nawet powyżej wydajności pamięci), ponieważ chodzi tu raczej o projektowanie użytkownika niż o maksymalne wykorzystanie sprzętu. Często zdominuje projekty interfejsów i sposób, w jaki budujemy całą naszą bazę kodu w takich scenariuszach.

Kiedy nie ograniczamy się jedynie do zacieśnienia pętli dostępu do ogromnej struktury danych, wielowątkowość przechodzi do naprawdę ostrej kategorii „projektowanie”, a projektowanie zawsze przebija implementację.

Tak więc w tych przypadkach powiedziałbym, że rozważenie wielowątkowości z góry jest absolutnie niezbędne, nawet bardziej niż reprezentacja pamięci i dostęp.


0

Najważniejsze staje się programowanie równoległe i równoległe. Wątki są tylko jednym modelem programowania do robienia wielu rzeczy jednocześnie (a nie w pseudo-równoległych, jak to miało miejsce przed powstaniem procesorów wielordzeniowych). Wielowątkowość jest (IMHO dość) krytykowana za to, że jest złożona i niebezpieczna, ponieważ wątki mają wiele zasobów, a programista jest odpowiedzialny za ich współpracę. W przeciwnym razie dojdzie do impasu, który jest trudny do debugowania.


0

Ponieważ może być konieczne skontaktowanie się z wieloma aplikacjami zewnętrznymi, może wystąpić proces w tle, w którym interakcja z systemem zewnętrznym zajmuje więcej czasu, a użytkownik końcowy nie może czekać, aż proces się zakończy. więc wielowątkowość jest ważna ...

używamy w naszej aplikacji, najpierw próbujemy skontaktować się z systemem zewnętrznym, jeśli jest wyłączony, następnie zapisujemy żądanie w bazie danych i rozpinamy wątek, aby zakończyć proces w tle. Może być również wymagane w operacjach wsadowych.


0

Historycznie ludzie musieli walczyć, wykonując programowanie wielowątkowe ręcznie. Musieli pracować ze wszystkimi podstawowymi komponentami (wątki, semafory, muteksy, zamki itp.) Bezpośrednio.

Wszystkie te wysiłki zaowocowały aplikacjami, które były w stanie skalować, dodając dodatkowy procesor do jednego systemu. Ta wertykalna skalowalność jest ograniczona przez „jaki jest największy serwer, jaki mogę kupić”.

Obecnie widzę zmianę w kierunku korzystania z większej liczby ram i różnych modeli projektowych do projektowania oprogramowania. MapReduce to jeden z takich modeli, który koncentruje się na przetwarzaniu wsadowym.

Celem jest skalowanie w poziomie. Dodanie bardziej standardowych serwerów zamiast kupowania większych serwerów.

Mimo to faktem jest, że naprawdę zrozumienie programowania wielowątkowego jest bardzo ważne. Byłem w sytuacji, gdy ktoś stworzył warunek wyścigu i nawet nie wiedziałem, co to jest wyścig, dopóki nie zauważyliśmy dziwnych błędów podczas testów.


-1

Moja maszyna ma 8 rdzeni. W Menedżerze zadań mam uruchomionych 60 procesów. Niektóre, jak VS, używają do 98 wątków. Outlook używa 26. Spodziewam się, że większość mojego wykorzystania pamięci to stosy przydzielone do każdego z tych bezczynnych wątków.

Osobiście czekam na pojawienie się 300-rdzeniowego komputera, aby nie musiałem czekać na odpowiedź programu Outlook. Oczywiście do tego czasu Outlook będzie używał 301 wątków.

Wielowątkowość ma znaczenie tylko wtedy, gdy budujesz systemy, które będą jedynym ważnym procesem na komputerze w danym momencie (np. Silniki obliczeniowe). Aplikacje komputerowe prawdopodobnie zrobiłyby dla użytkownika przysługę, nie zużywając każdego dostępnego rdzenia. Aplikacje internetowe korzystające z modelu zapytania / odpowiedzi są z natury wielowątkowe.

Ma to znaczenie dla projektantów frameworków i języków oraz programistów systemów zaplecza - nie tyle dla twórców aplikacji. Jednak zrozumienie niektórych podstawowych pojęć, takich jak blokowanie i pisanie kodu asynchronicznego, jest prawdopodobnie warte zachodu.


Ja często walnięcie coś na wątek tła, takich jak długi obciążenia DB, ale jest bardzo rzadko mam do czynienia z warunkami rasy czy zamki itp (w rzeczywistości prawdopodobnie nigdy)
Aran Mulholland
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.