Fork-Join rozwoju w Java™ SE

Source : http://www.coopsoft.com/ar/ForkJoinArticle.html

Fork-Join do codziennego, multi-core aplikacje Java

Fork lub rozdzielanie obciążenia na wiele zadań, do równoległego przetwarzania i łączenia wyników razem to technika stosowana w niezliczonych naukowe numer, rzewnym aplikacje. Wiele innych aplikacji może korzystać z dok-dołącz do przetwarzania, ale używając podejścia naukowego nie mogą być w ich najlepszym interesie.

Niniejszy artykuł prezentuje “kłopotliwie równoległych” dok-dołącz do podejścia, które dobrze sprawdza się w codziennym użytkowaniu, wielordzeniowej aplikacji Java SE, ME jak również Android.™ (3000 słów)

Edward Harned (eh at coopsoft dot com)
Starszy programista, spółdzielnia Software Systems, Inc.
Luty 2010 [aktualizacja: czerwiec, 2013]

Jaka jest Fork-Join?

Pomyśl o widełki w road, gdzie każda droga w końcu znowu razem – kompletowi.

Pęknie Fork-Join aplikacji na kilka czesci do przetwarzania równoległego i faszystowskiej wyniki na końcu.

f-j

Rysunek 1: Struktura Fork-Join

Powiedzmy mamy macierz tysiąc numerów. Musimy zrobić procedurę w każdym z tych numerów i dodać całkowitą.

Lista 1: przetwarzanie matrycowe

For (int i = 0; i < 1000; i++) {
Total += doProcedure(array[i]);
}

Jeśli procedura trwa jedną sekundę (Wall-clock time) odbycia stażu, a następnie jest kierowana do wzięcia tysiąc sekund (ponad 16½ minuty) do wykonania tego zadania.

Fork-Join mógłby

  • Oddzielne (widełki) dużych macierzy do macierzy 10 stu elementów każdego,
  • Procesy każda macierz na osobnym CPU, i
  • Dołącz wyniki po zakończeniu.

Że zaniesie sto sekund (nieco ponad 1½ – 60 minut), jedną dziesiątą w pierwotnym terminie. Więcej CPU, tym szybszy efekt.

To właśnie praca naukowa to opowieść o – jednocześnie humongous przetwarzanie olbrzymich ilości danych na wielu CPU jako dostępne. Ta abstrakcja przypomina standardowy model naukowych dziel i rządź.

Dziel i rządź jest naturalny paradygmat dla algorytmów równoległych. Po podzielenie problemu na dwa lub więcej sub-problemy, metodę rozwiązującą sub-problemy w układzie równoległym. Zazwyczaj, sub-problemy są rozwiązane rekursywnie, a tym samym kolejnego podziału kroku przynosi jeszcze więcej sub-problemy do rozwiązania w układzie równoległym.

Rysunek 2: dziel i rządź

dac

Problemy za pomocą Fork-Join model naukowy do codziennych zastosowań

Tworzenie zadań nie jest problemem; są tylko obiekty. Problemem jest duża liczba wątków przetwarzania zadań podczas tych zadań potrzebne są:

Połączenia
Uzyskiwanie dostępu do usług zdalnych (DBMS, Messaging, a także wiele innych) wymaga połączenia z usługą zdalną. Ogólnie, zdalne usługi za pomocą gwintu do obsługi połączenia i wymaga pamięci, przełączanie kontekstu, synchronizacji i koordynacji ruchów. Im więcej połączeń do serwisu, tym więcej zasobów na potrzeby serwisu, a mniej połączeń do innych zadań w JVM. To dotyczy każdego użytkownika.

Zamki
Zamki są zabójcze dla wysokiej wydajności. Martwych/live zamki, priority inversion, głodzenie, convoying i narzut (która rośnie wykładniczo w stosunku do długości listy oczekujących zadań) są pewne problemy z zastosowaniem zamków.

Semafory
Im więcej wątków, które chcą umożliwić jednocześnie, więcej wątków, które muszą poczekać na dostępność. To sprowadza nas z powrotem do wszystkich problemów za pomocą zamków.

Spójności pamięci podręcznej
Kiedy wielu procesorów dostęp/aktualizacja tej samej zmiennej wewnątrz linii cache, (blok danych kopiowanych z głównej pamięci zawierających wiele pól), moduł pamięci może unieważnić cache line. Że nie tylko spowalnia aplikację, może wpływać na innych aplikacji, jak również.

Obszerna pamięć
Im więcej obiektów lub większych obiektów, tym więcej pamięci. Więcej aktywne wątki obsługi zadań, wówczas więcej pamięci w obsłudze. Oczywiście, wynika z tego, że duża pamięć zadań potrzeba przepustu.

Potrzeba play nice
Gracz nie może stanowić jedynej aplikacji uruchomionych na komputerze. Podczas jednej aplikacji guźce zasoby, każdy czuje ból. Gra nice z innymi, wraca do tego, co wszyscy mamy wyuczone w dzieciństwie. To samo dotyczy pisząc oprogramowanie nie działa jako samodzielna aplikacja.

Wątek multi-core development jest niedopuszczenie do rywalizacji, zadań konkurują o te same zasoby, do minimum.

Jeśli dynamicznych dekompozycja paradygmat dziel i rządź odpowiada Twoim potrzebom, a potem przeczytaj ten artykuł o wysokiej wydajności DSE version of Tymeac. W przeciwnym razie to funkcjonalna fork Framework może lepiej dopasowane do twoich potrzeb.

Funkcjonalne Fork Framework

Java™SE / ME multi-core, jak również system operacyjny Android™, nie można korzystać z tych dziel i rządź model, nie przetwarzać duże tablice liczb, lub nie posiadają intensywne potrzebne struktury funkcjonalnej fork ram parallelizing aplikacje. Konkretnie, których potrzebują do talerza prac na jego funkcjonalne elementy zamiast rozkładać macierzy w identycznych subtasks.

factor

Rysunek 3: funkcjonalny fork Framework

Funkcjonalny fork framework posiada dwie zasadnicze cechy. Należy:

  • Ograniczenia rywalizacji.
  • Prosty w obsłudze lub kłopotliwie równoległych.

Ograniczenia rywalizacji

Utrzymanie liczby aktywnych, konkurujące ze sobą wątki do absolutnego minimum jest najważniejsza. Najprostszym sposobem na ograniczenie wątek rywalizacji jest stosowanie progów dla każdej puli wątków obsługa kolejki zadań. Zobacz ten artykuł na High Performance Priority Queues in Java SE przykład, jak za pomocą Wait List może oszczędzać zasoby gwint.

Waloryzacja zasobów zamiast akwizycję nowych kopii zasobów jest zwyciężczyni All-around. Musimy wziąć pod uwagę nie tylko kod zadania, ale zarządzanie zasobami kodu jak również.

Weźmy przykład zadania wymagające dostępu do bazy danych, która wymaga [java.sql.]oświadczenie. Korzystając z kolejki żądań, kod zadania mogą dzielić to samo oświadczenie dla wielu wywołuje raczej następnie nabywających nowe zestawienie dla każdego access. Udostępnianie oświadczenie  to ogromne oszczędności w koszty i ogranicza rywalizację w ramach zarządzania kodem.

Jaka jest kłopotliwie równoległych?

Kłopotliwie równoległych algorytmów są te, które mogą rozwiązać wiele podobnych, ale niezależnych zadań jednocześnie z niewielką potrzebę koordynacji pomiędzy zadaniami. Tego rodzaju problemy, takie proste równomierne obciążenie sieciowe podzielone, że jeden jest prawie “wstydzę”, by opowiedzieć o tym, jak łatwo jest się wielu przetwórców pracować wydajnie.

Jest kłopotliwie równoległych rozwiązania mogą łatwo widełki na kilka całkowicie niezależnych składników, każdy wykonujący na oddzielnym procesorem.

Rysunek 4: Kłopotliwie równoległych

fjGraph

Na przykład:
Firma może potrzebować automatyczną wycenę systemu. Rozwinięcie cytatu, system potrzebuje obiektu cena podstawowa cena (bazy danych), klienta rabat dla pozycji i rzecznych (bazy danych klientów), a podstawowe koszty wysyłki (wysyłający bazy danych).

Tradycyjnie, program umożliwia dostęp do każdej bazy danych połączone, czekającym na każdy dostęp do pełnych, zanim przejdzie do następnej.

W równoległym układzie, program widły() żądanie na trzy kolejki, każde obsługiwane przez thread pool, czeka, aż ostatni dostęp wykończenia oraz kompletowi() wyniki razem.

Rysunek 5: oferta cenowa

pricequote

Powyższa wycena jest przykładem synchroniczne żądanie, gdzie dzwoniący czeka na zakończenie. Jest tylko jeden mały krok do przodu w celu dodania obsługi asynchronicznych lub autonomicznych wniosek, jeżeli rozmówca nie czekać na zakończenie.

Istnieje wiele, wiele sytuacji, w których fork prac na jej elementów jest pożądane:

  • Zachęcamy do gry, w którym możemy widełki zdarzenie na oddzielne elementy. Zaletą jest tu emocji; im więcej segmentów zdarzeń odbywających się równocześnie, ciekawsze gry.
  • Podjęcie wniosku z wielu animacji, gdzie możemy widełki każdą animację, aby pracować na własny procesor.
  • Pobrać obraz operacji przetwarzania, gdzie każdy pixel obrazu musi mieć swój kolor odwrócona. Ramach można łatwo rozpowszechniać danych obrazu do wielu zadań, które mogą pracować niezależnie od siebie.
  • Podjęcia przez instytucję finansową, gdzie ponownie doceniania portfolio obejmuje elementy, które komunikują się z różnych rynków na całym świecie.
  • Podjęcie opieki zdrowotnej wniosek gdzie różne testy są elementy diagnozy.

To starania, aby zobaczyć to, czego nie może użyć równomierne obciążenie sieciowe podzielone za pomocą funkcji fork framework.

Jak miałoby to wyglądać framework w aplikacji Java™ aplikacji?

Ramy do rozwidlania wniosek do jego funkcjonalne elementy potrzebne do:

Znajomość elementów (kolejki) dla każdego żądania (Funkcja) prostej klasy zawierające ciąg nazwy funkcji oraz listę powiązanych kolejek jest podstawowa Java™ programowania.

Lista 2: Funkcja klasy

Publiczne klasy funkcji {      Private String   nazwa; // nazwa funkcji
 Kolejki prywatne[] que;   // kolejek do tej funkcji
}

Miejsce wniosek (zawierający obiekty wejściowe) do każdej z kolejek zwracanie obiektu array rozmówcy bądź lekceważenie zwróconych obiektów.

Lista 3: Umieść w kolejce

Public Object[] wideł kolejki([] que, Object request) {Object[] powrót_obj = new Object[] {null” null” null};

For (int i = 0; i < que.length; i++) {
PutInQueue(que[i], zwrot_obj [ja], zwany dalej “wnioskiem”);
}

      Powrót return_obj.
}

Zaczekaj na zakończenie/limit czasu lub nie czekali.

Lista 4: Czekaj/noWait

Public boolean dołącz(object[] obj) {/* jeśli wszystkie elementy są non-null, return true
* odczekać chwilę
* po przerwie, return false
*/.
}

Powrót wyniki do rozmówcy lub zignorować obiekty

Rysunek 6: powrót do dzwoniącego

 

 back

 

 

 

Do zbudowania tego framework byśmy:

  1. Konieczność utrzymania rzeczywistej kod zadania, które wykonuje pracę
  2. Trzeba utrzymywać listę kolejek i funkcje
  3. Konieczność utrzymania “start up” klasa, która wczyta kolejek i funkcje do pamięci

(1) kod, który wykonuje pracę powinno wyglądać tak:

Lista 5: Kodeks Pracy

Publicznego statycznego obiektu głównego(object obj) {}

Main() metoda akceptująca obiektu (wejście od dzwoniącego) i powraca do obiektu (wynikiem prac).

(2) będziemy mogli utrzymać kolejek i funkcje jako obiekty w obrębie prostą listę klasy.

(3) Uruchamianie może wystarczy załadować listę klas do pamięci o nowej liście (klasa) i uruchomić wątki dla każdej kolejki.

Jak zwykła rozmowa może wyglądać:

Lista 6: zwykła rozmowa

Framework fw = new Framework();// Dla każdego połączenia:
Funkcja func = fw.getFunction(name);
Object[] powrót = func.wideł(wniosek};

Ramy te są proste w obsłudze, kłopotliwie proste.

Podsumowanie

Do tej pory widzieliśmy jak fork wniosek do jego funkcjonalne elementy mogą pracować jako wbudowane części pojedynczej aplikacji (w tej samej JVM). By być praktyczne, musimy również upewnić ram dostępny z innymi instancjami JVM. Wystarczy, że musi obsługiwać wiele połączeń jednocześnie jako serwer.

Co sprawia, że jest to Server

Jakie zmiany muszą sprawić, by zawiązać ten prosty framework do serwera?

  1. Musimy oddzielić rozmówcy z pracy.
  2. Musimy zapewnić błedów.
  3. Musimy wspierać framework jako odległy obiekt.
  4. Musimy zapewnić bezpieczeństwo.
  5. Musimy zapewnić funkcji administracyjnych do kontrolowania serwera.

Separacja
Pierwsza zmiana jest separacja wniosek pośrednictwa (to powyżej wideł()) z faktycznym przetworzeniu. Musimy oddzielić, ale śledzić, każdy wniosek w unikalny obiekt.

Lista 7: Żądanie obiektu

  Prywatne długi             unique_id; // Unikalna identyfikacja tego żądania
  Prywatny obiekt             wejściowy; // input odniesienie, jeżeli jakiekolwiek
  Private boolean          type; // typ żądania true=sync false=async
  Private Object[]          // produkcja obiektów z zadań
  Prywatne AtomicInteger next_output; // subscript w celu dodania elementu do temperatury powyżej
 Kolejki prywatne[]         que_names; // Lista wszystkich kolejek w tej funkcji
 Kolejki prywatne             agent; // kolejka w przyszłości, jeżeli stosowany)
  Prywatne AtomicInteger nbr_remaining; // kolejki pozostały do obrobienia
  Private int                 wait_time; // max czas oczekiwania na żądanie synchronizacji

Co to jest pole “agent”?

Agent
Synchroniczne żądanie zwraca obiekt array od przetwarzania do rozmówcy. Co powinien zrobić ramy z obiektu array wracały z asynchroniczne żądanie? Ramach można opcjonalnie umieścić obiekt array (jako nakład) na nową kolejkę do przetworzenia przez agenta zadania. W ten sposób zadanie agenta może podjąć działania na podstawie status zakończenia wcześniejszej obróbki.

Na przykład:
Funkcja jest do generowania o wycenę i je pocztą e-mail do użytkownika jak asynchroniczne żądanie.

  1. Rozmówca używa asynchronicznego widełki().
  2. Ramach widły wniosek do odpowiednich kolejek.
  3. Po ostatniej kolejce wykończeń, ram przechodzi zwróconego obiektu array do zadanie agenta poprzez wprowadzenie wniosku do kolejki okreoelone jako “agent”.
  4. Agent zadanie wysyła email powrót nic nie pomoże.

Naprawianie błędów
Drugą zmianą jest dodanie błedów, znak profesjonalizmu.

Co może pójść źle? “Wszystko Co może pójść nie tak, będzie gorzej.” Murphy’s Law.

Powrót
Moglibyśmy mieć błąd fork. Bounded kolejki może być pełna lub kolejki może być wyłączona (więcej o tym poniżej). błedów powinien cofnąć wszystkich kolejek, rozwidlone pomyślnie i informuje dzwoniącego o problemie. Na przykład:

  • Mamy trzech kolejek (A, B, C) w funkcji.
  • Kolejek A i B z powodzeniem otrzymywać żądania.
  • Kolejka C nie odbiera żądania, ponieważ kolejka jest pełna.
  • Teraz idziemy do tyłu, próbując wyciągnąć wniosek, ze wszystkich kolejek, rozwidlone pomyślnie dzięki czemu możemy zaoszczędzić czas przetwarzania uszkodzone żądania.

Wyjątek/Error
Moglibyśmy mieć wyjątek/błąd w aktualnie panujących kod, który wykonuje pracę. Jeśli on nie raz, że prawdopodobnie będzie działać ponownie. Dlatego zaleca się, aby wyłączyć kolejkę aż deweloper rozwiązuje problem. Gdy kod zadania jest czyste, nie chcemy strącić z serwera. Chcemy, aby poinformować serwer, że mamy nową kopię kodu zadania, która jest czysta i chcemy kolejki enabled.

Ciśnienie dławienia
Moglibyśmy mieć powyżej nastąpi w asynchroniczne żądanie, tzw. stall (synchroniczne żądania time out i można usunąć z systemu.) od funkcji nie zakończony, dopóki wszystkie kolejki wykończeniem, musimy umieścić zgasł żądania na zdławionych listy. Gdy kolejka jest ponownie naprawialne, możemy ponownie uruchomić od przetwarzania zgasł listy.

Expunging stanowi przedmiot ku sobie i wymaga zamknięcia wątku. Artykuł ten wprowadza temat: Managing Threads in Java SE

Thread rozterce
Moglibyśmy mieć gwint blok forever na zewnątrz zasobu lub przejść do nigdy nie kończących się pętli. Tak czy owak, dzięki synchronizacji wydarzeń z życia wątku, framework mogą uznać tę sytuację i może expunge gwint zastąpiono go nowym wątku.

Anulowanie
Moglibyśmy mieć rozmówców chcesz anulować wcześniej złożony wniosek. Cancel jest podobna do time-out błędu, ale konieczne jest zastosowanie zarówno do synchronicznych i asynchronicznych żądań. Chociaż anulowanie żądania jest najbardziej pożądana, logika obsługi anulowania w ¶rodowisku podzespołu nie jest za słabe serce.

Monitorowanie
Rozrząd jest zbyteczny chyba demonem wątek monitoruje zdarzenia czasowe szukając rzeczywistych lub potencjalnych problemów.

Powiadomienie
Ram nie poradzi sobie w każdej sytuacji; czasami konieczne działania mogą być podjęte bez interwencji człowieka. Powinniśmy powiadomić administratorów, wysyłając wiadomość za pośrednictwem jakichkolwiek środków przez organizację (Instant Messaging, email, lub jakakolwiek inicjatywa dotycząca metody).

Obiekt zdalny
Trzecia zmiana popierającą framework jako odległy obiekt z opcją włączenia/wyłączenia funkcji umożliwiających oszczędzanie zasobów.

Remote Method Invocation przychodzi wiele smaków:
Podstawowe
Gniazdo Custom Factory
IIOP.
Portable Object Adapter
Jini
Inter komunikacji międzyprocesowej

Twoje otoczenie może składać się z obłoku z oddzielnych procesorów w wielu różnych miejscach. W ramach elastycznych nabiera sensu.

Bezpieczeństwo
Czwarta zmiana jest dodawanie zabezpieczeń.

Java™ security technology jest częścią SE/ME Platform, wymaga ona przed niekończącym się serwer z klas bezpieczeństwa na elastyczność.

Funkcje dostępu na poziomie administratora
Piątą zmianą jest dodanie funkcji administratora.

Logowanie jest nudna i głównie bezpożyteczne, aż coś pójdzie nie tak.

Statystyki są podstawą do analizy wydajności i strojenie.

Musimy dostarczać interfejsy do wewnętrznej struktury, dzięki czemu użytkownicy mogą monitorować i kontrolować funkcje. Nie jest też wiele dobrego, jeśli nikt nie wie, co robi. Kiedy ludzie wiedzą co to robią, zapewne będzie chciała go zmienić.

Napisałam Fork-Join framework, który jest prosty w użyciu i skuteczny dla połączeń lokalnych jest trudna. Ten sam dostęp do sieci to poważne przedsięwzięcie.

Jak długo będzie on do zbudowania takiego serwera?

Około 5-6 sekund. Tylko na tyle długo, aby rozpakować plik.

Szczęśliwie, nie są uniwersalne, dok-dołącz szkielety wspieraniu właściwości wymienionych powyżej do codziennego, wielordzeniowej aplikacji Java SE, ME i Android Market™ dostępny już dziś. A ponieważ ram może pracować jako serwer RMI (standard/aktywowalna, IIOP i POA) dostępny jest dla Java EE aplikacje.

Tymeac™ for Java™ SE / ME / Android™ platformy oprogramowania Open Source projekty na krawężniku
I możesz pobrać najnowsze wersje.

Zawarcie

Za pomocą Fork-Join opracowanym dla intensywnych społeczności mogą nie działać prawidłowo w przypadku prostych aplikacji.

Gro Java™ multi-core aplikacje wymagają wideł (do prac na jego funkcjonalne elementy za pomocą profesjonalnych ramach, które jest łatwe w obsłudze, wydajne i open-source.

Odsyłacze

Pliki do pobrania:

Pobierz najnowszą wersję SE edition Tymeac here. Z całej dokumentacji, skrypty, klasy i źródła.

Pobierz najnowsze  wydanie mnie Tymeac here. Z całą dokumentację i źródła.

Pobierz najnowszą wersję i wydanie Tymeac here. Z całą dokumentację i full eclipse projekty.

Pobierz najnowszy wynik wskazywał edition Tymeac here. “dziel i rządź wersji.

Artykuły:

Wysoka wydajność dziel i rządź wersja Tymeac – A Java Fork-Join Conqueror

Wysokowydajny system operacyjny Android™ wersja Tymeac – Managing Threads in Android

Za pomocą listy oczekiwania dotyczące wydajności – High Performance Priority Queues in Java SE

Java™ SE wątek kontener – Managing Threads in Java SE

Inne:

Dok – dołącz do kolejki wiki – http://en.wikipedia.org/wiki/Fork-join_queue

Prawa Murphy’ego prawa – http://en.wikipedia.org/wiki/Murphy%27s_law

Pamięć podręczna procesora wiki – http://en.wikipedia.org/wiki/CPU_cache

Spójność pamięci podręcznej wiki – http://en.wikipedia.org/wiki/Cache_coherence

Kłopotliwie równoległych wiki – http://en.wikipedia.org/wiki/Embarrassingly_parallel

O autorze

Edward Harned Jest programistą z ponad trzydziestoletnim doświadczeniem w branży. On pierwszy led projekty jako pracownik w głównych gałęziach przemysłu, a potem pracował jako niezależny konsultant. Dziś, wyd. jest starszy programista w Cooperative Software Systems, Inc., gdzie przez ostatnie 12 lat, on ustawił Java™ programowania aby ustawić widełki-dołącz do rozwiązania dla szerokiego zakresu zadań.