WIELOWĄTKOWOŚĆ. Waldemar Korłub. Platformy Technologiczne KASK ETI Politechnika Gdańska

Podobne dokumenty
Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Java. Programowanie Obiektowe Mateusz Cicheński

Wątki. Definiowanie wątków jako klas potomnych Thread. Nadpisanie metody run().

Obliczenia równoległe i rozproszone w JAVIE. Michał Kozłowski 30 listopada 2003

Wielowątkowość. Programowanie w środowisku rozproszonym. Wykład 1.

Język Java wątki (streszczenie)

Aplikacje w Javie- wykład 11 Wątki-podstawy

Interfejsy w Java. Przetwarzanie równoległe. Wątki.

Programowanie komputerów

Wątki w Javie. Piotr Tokarski

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Język Java wątki (streszczenie)

Kurs programowania. Wykład 8. Wojciech Macyna

Programowanie równoległe i rozproszone. W1. Wielowątkowość. Krzysztof Banaś Programowanie równoległe i rozproszone 1

WSPÓŁBIEŻNOŚĆ. MATERIAŁY:

Autor: dr inż. Zofia Kruczkiewicz, Programowanie aplikacji internetowych 1

Kurs programowania. Wykład 8. Wojciech Macyna. 10 maj 2017

Nowinki technologiczne procesorów

Podstawy współbieżności

Stworzenie klasy nie jest równoznaczne z wykorzystaniem wielowątkowości. Uzyskuje się ją dopiero poprzez inicjalizację wątku.

Mechanizmy pracy równoległej. Jarosław Kuchta

Współbieżność w Javie

Współbieżność w środowisku Java

1 Wątki 1. 2 Tworzenie wątków 1. 3 Synchronizacja 3. 4 Dodatki 3. 5 Algorytmy sortowania 4

Tworzenie i wykorzystanie usług

Współbieżność w Javie

Języki i Techniki Programowania II. Wykład 7. Współbieżność 1

Programowanie wielowątkowe. Tomasz Borzyszkowski

Nowinki technologiczne procesorów

Programowanie równoległe i rozproszone. Praca zbiorowa pod redakcją Andrzeja Karbowskiego i Ewy Niewiadomskiej-Szynkiewicz

Wykład 6. Rafał Skinderowicz

Nowinkach technologicznych procesorów

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Programowanie współbieżne Wykład 2. Rafał Skinderowicz

Zaawansowany kurs języka Python

Programowanie równoległe i rozproszone. Monitory i zmienne warunku. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Programowanie współbieżne i rozproszone

Model pamięci. Rafał Skinderowicz

Platformy Programistyczne Zagadnienia sieciowe i wątki

Programowanie współbieżne Laboratorium nr 11

Multimedia JAVA. Historia

Wykład 5. Synchronizacja (część II) Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

Task Parallel Library

Wielowątkowość mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Wywoływanie metod zdalnych

Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Aplikacja wielowątkowa prosty komunikator

Przykłady interfejsu TCP i UDP w Javie

Kurs języka Python. Wątki

Programowanie obiektowe

Budowa komputera. Magistrala. Procesor Pamięć Układy I/O

Singleton. Cel: Przykład: Zastosowanie: Zapewnienie, że klasa ma tylko jedną instancję i dostarczenie globalnego dostępu do niej.

Wywoływanie metod zdalnych

Enkapsulacja, dziedziczenie, polimorfizm

WPŁYW PROGRAMOWANIA RÓWNOLEGŁEGO NA WYDAJNOŚĆ PROGRAMU JAVY

Sprzęt komputerowy 2. Autor prezentacji: 1 prof. dr hab. Maria Hilczer

Java Podstawy. Michał Bereta

akademia androida Service, BroadcastReceiver, ContentProvider część IV

Język Java część 2 (przykładowa aplikacja)

Algorytmy i Struktury Danych. Anna Paszyńska

Kurs rozszerzony języka Python

Programowanie rozproszone w języku Java

Metody Metody, parametry, zwracanie wartości

Wprowadzenie do programowania współbieżnego. Grafika, Proste Animacje

Programowanie współbieżne Wykład 5. Rafał Skinderowicz

Zaawansowane programowanie w C++ (PCP)

Programowanie współbieżne Laboratorium nr 12

RDZEŃ x86 x86 rodzina architektur (modeli programowych) procesorów firmy Intel, należących do kategorii CISC, stosowana w komputerach PC,

PROGRAMOWANIE WSPÓŁCZESNYCH ARCHITEKTUR KOMPUTEROWYCH DR INŻ. KRZYSZTOF ROJEK

RESTful Android. Na co zwrócić uwagę przy tworzeniu aplikacji klienckich REST na Androidzie

Instrukcja implementacji sterownika wirtualnego portu szeregowego dla systemu Android. Opracowanie: Elzab Soft sp. z o.o.

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Zadanie 2: transakcyjny protokół SKJ (2015)

Programowanie wielowątkowe. Jarosław Kuchta

Programowanie współbieżne Wykład 2. Iwona Kochańska

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

Java podstawy jęyka. Wykład 2. Klasy abstrakcyjne, Interfejsy, Klasy wewnętrzne, Anonimowe klasy wewnętrzne.

Java: interfejsy i klasy wewnętrzne

Narzędzia i aplikacje Java EE. Usługi sieciowe Paweł Czarnul pczarnul@eti.pg.gda.pl

msgbox("akcja: Początek, argument: " + argument.tostring()); Thread.Sleep(1000); //opóźnienie msgbox("akcja: Koniec"); return DateTime.Now.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

Budowa komputera. Magistrala. Procesor Pamięć Układy I/O

Aplikacje RMI Lab4

Aplikacja wielow tkowa prosty komunikator

Programowanie obiektowe i zdarzeniowe

Programowanie w Javie 1 Wykład i Ćwiczenia 3 Programowanie obiektowe w Javie cd. Płock, 16 października 2013 r.

Komunikacja z użyciem gniazd aplikacje klient-serwer

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

Aplikacje internetowe i rozproszone - laboratorium

Aplikacje RMI

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Programowanie i projektowanie obiektowe

Przetwarzanie równoległe i współbieżne

Sprzęt komputerowy 2. Autor prezentacji: 1 prof. dr hab. Maria Hilczer

Systemy Rozproszone - Ćwiczenie 4

Model pamięci. Rafał Skinderowicz

Semafor nie jest mechanizmem strukturalnym. Aplikacje pisane z użyciem semaforów są podatne na błędy. Np. brak operacji sem_post blokuje aplikację.

Transkrypt:

WIELOWĄTKOWOŚĆ Waldemar Korłub Platformy Technologiczne KASK ETI Politechnika Gdańska

Wydajność 2 Do 2005 roku wydajność komputerów poprawiano zwiększając częstotliwość taktowania procesora 1995: Pentium Pro 200 MHz 2005: Pentium 4 3,8 GHz 2017: Core i7-7700k 4,2 GHz ~19-krotny wzrost częstotliwości taktowania Dalsze zwiększanie częstotliwości jest trudne ze względu na ilość emitowanego ciepła Po 2005 roku rozwój w zakresie efektywności energetycznej i wielordzeniowości 2017: Xeon E7-8894 v4 n 2,4 GHz (3,6 GHz z Turbo Boost) n 24 rdzenie fizyczne + Hyper-Threading 48 wątków

Wydajność 3 Obecnie podstawową metodą przyspieszania obliczeń jest ich zrównoleglenie Wiele wątków/procesów na CPU n Przetwarzanie rozproszone, platformy technologiczne Akceleratory obliczeniowe, karty graficzne n Przetwarzanie równoległe CUDA Wiele węzłów połączonych w ramach klastra n Systemy obliczeniowe wysokiej wydajności

Zrównoleglenie obliczeń na CPU 4 Wiele procesów Osobne instancje aplikacji Każda z osobną przestrzenią adresową Komunikacji między procesami (IPC): potoki, pliki, gniazda (ang. sockets), RPC, itd. Wielowątkowość Wiele wątków w obrębie jednego procesu Wspólna przestrzeń adresowa n Wymiana informacji między wątkami przez współdzielone zmienne konieczna synchronizacja dostępu

Zastosowania (tylko niektóre) 5 Szybsze przetwarzanie danych Eksport materiału wideo Uczenie głębokie Szybsza kompresja/dekompresja plików Aplikacje serwerowe Obsługa wielu klientów równocześnie Serwery HTTP Systemy transakcyjne

Wielowątkowość w Javie 6 Thread + Runnable Najbardziej niskopoziomowe API Sekcje krytyczne (synchronized) Kontrolują dostęp do współdzielonych obiektów java.util.concurrent.* ExecutorService ułatwia zarządzanie pulą wątków roboczych i zadaniami do wykonania Implementacje typowych wzorców dla programowania równoległego, np. blokady cykliczne, semafory, kolejki zadań Fork/Join Framework Dla problemów klasy dziel i rządź Parallel Stream Współbieżna obsługa strumieni

Dziedziczenie po klasie Thread niezalecane 7 Przygotowanie wątku przez dziedziczenie po klasie Thread Należy nadpisać metodę run() operacje do wykonania w osobnym wątku Metoda start() uruchamia nowy wątek Niezalecane n Wiąże zadanie do wykonania ze sposobem jego uruchomienia n Thread jest klasą dziedzicząc po klasie Thread nie można dziedziczyć po innych klasach

Thread + Runnable 8 Zadanie do wykonania definiowane jako obiekt implementujący interfejs Runnable Możliwość dziedziczenia po innych klasach Runnable jest interfejsem funkcyjnym (pojedyncza metoda run()) możliwość zastosowania wyrażenia lambda Obiekt implementujący Runnable należy przekazać jako argument konstruktora klasy Thread Thread.start() uruchamia wątek w tle

Thread + Runnable 9 private void longrunningjob(string path, int counter){ //...długotrwałe i intensywne //obliczeniowo operacje... } //przygotowanie zadania w innej metodzie: Runnable task = () -> this.longrunningjob("/home/stwrl/tmp", 42); //uruchomienie wątku: Thread thread = new Thread(task); thread.start();

Oczekiwanie na zakończenie zadania 10 Oczekiwanie na zakończenie zadania wywołanie blokujące: thread.join(); Sprawdzenie stanu zadania wywołanie nieblokujące: if (thread.isalive()) { //operacje ciągle trwają } else { //operacje się zakończyły }

Przerwanie wątku anulowanie zadania 11 Wątek można przerwać bez oczekiwania na zakończenie wykonywanego zadania: thread.interrupt(); Wątek otrzymujący przerwanie powinien zwolnić wykorzystywane zasoby (np. uchwyty plików, gniazda sieciowe) i zakończyć działania Skąd wątek wie, że otrzymał przerwanie? Wyjątek InterruptedException n O ile wątek jest w trakcie wykonywania metody, która może wyrzucić taki wyjątek Sprawdzenie przerwania metodą Thread.interrupted();

Przerwanie wątku 12 while (!Thread.interrupted()) { //przetwarzanie danych } try { //oczekiwanie przed kolejną iteracją Thread.sleep(1000); } catch (InterruptedException e){ break; } //zwolnienie zasobów //zakończenie zadania

Potrzeba synchronizacji 13 Pewne sekcje programu nie powinny być wykonywane przez wiele wątków równocześnie Integer tmp = this.counter; tmp = /*...złożone obliczenia...*/ tmp + 2; this.counter = tmp; Wątek nr 1 Wątek nr 2 tmp = 17 tmp = 17+2 = 19 counter = 19 tmp = 17 tmp = 17+2 = 19 counter = 19

Synchronizacja sekcja krytyczna 14 synchronized (this) { } Integer tmp = this.counter; tmp = /*...złożone obliczenia...*/ tmp + 2; this.counter = tmp; Wątek nr 1 Wątek nr 2 tmp = 17 tmp = 17+2 = 19 counter = 19 tmp = 19 tmp = 19+2 = 21 counter = 21 lub Wątek nr 1 Wątek nr 2 tmp = 17 tmp = 17+2 = 19 counter = 19 tmp = 19 tmp = 19+2 = 21 counter = 21

Synchronizacja sekcja krytyczna 15 Jeśli sekcja krytyczna ma obejmować całą metodą można użyć uproszczonej składni: public synchronized void calculate(){ Integer tmp = this.counter; tmp = tmp + /*...obliczenia...*/1; this.counter = tmp; }

16 Executor Service

Pule wątków 17 Przykład: aplikacja serwerowa Podejście #1: jeden wątek do obsługi wszystkich klientów Każdy kolejny klient oczekuje na zakończenie obsługi poprzedniego Podejście #2: uruchamiamy nowy wątek do obsługi każdego klienta Obsługa wielu klientów równocześnie 1000 klientów à 1000 wątków à zagłodzenie n Łatwość ataku typu Denial of Service Uruchomienie nowego wątku jest kosztowną operacją

Pule wątków 18 Podejście #3: pula wątków o określonym rozmiarze do obsługi klientów Obsługa wielu klientów równocześnie Liczba obsługiwanych równocześnie klientów dostosowana do możliwości serwera (np. liczby rdzeni CPU) n Uniknięcie zagładzania Jeśli klientów jest więcej niż wątków w puli, nadmiarowi klienci czekają na zwolnienie wątku roboczego Wątki w puli są uruchamiane przy starcie aplikacji n Uniknięcie kosztu wielokrotnego uruchamiania wątków w trakcie działania aplikacji n Zadania obsługi klientów uruchamiane w istniejących wątkach Rozmiar puli wątków może być dynamicznie dostosowywany do liczby klientów (obciążenia serwera)

Pule wątków 19 Na szczęście nie musimy implementować tego ręcznie Pula wątków o stałym rozmiarze: ExecutorService executor = Executors.newFixedThreadPool(4); Pula wątków o dynamicznym rozmiarze: ExecutorService dynamicexecutor = new ThreadPoolExecutor( 2, //minimalna liczba wątków 16, //maksymalna liczba wątków 60, //maksymalny czas nieaktywności wątku TimeUnit.SECONDS, new LinkedBlockingQueue<>() //kolejka zadań );

Pule wątków 20 Wysłanie zadania do puli wątków: executor.submit( () -> longrunningjob("/home/stwrl/tmp", 42)); Wysłanie zadania, które zwraca wartość: Future<Integer> future = executor.submit( () -> calculateresult("data.txt"));

Future<T> 21 Umożliwia sprawdzenie, czy zadanie zostało zakończone oraz pobranie jego wyniku get() oczekuje na zakończenie i zwraca wynik (wywołanie blokujące) isdone() sprawdza, czy zadanie zostało zakończone (nieblokujące) cancel() umożliwia anulowanie zadania

22 Fork/Join Framework

Fork/Join Framework 23 Wysokopoziomowe API dla zadań poddających się strategii dziel i rządź Zadanie definiowane jako klasa dziedzicząca po RecursiveTask Zadanie generuje rekurencyjnie nowe zadania o mniejszej złożoności etap fork Gdy zadania są wystarczająco małe następuje ich wykonanie Wyniki zadań są łączone w celu uzyskania końcowego rezultatu etap join

Sumowanie elementów tablicy: fork 24 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1

Sumowanie elementów tablicy: join 25 226 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 103 25 12 7 17 1 21 6 14 123 25 35 11 4 16 22 9 1 61 42 75 48 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 37 24 22 20 60 15 38 10 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1 25 12 7 17 1 21 6 14 25 35 11 4 16 22 9 1

class Sum extends RecursiveTask<Long> { static final int THRESHOLD = 5000; int low; int high; int[] array; } Sum(int[] array, int l, int h) { this.array = array; low = l; high = h; } protected Long compute() { if (high - low <= THRESHOLD) { long sum = 0; for (int i=low; i<high; ++i) { sum += array[i]; } return sum; } } int mid = low + (high - low) / 2; Sum left = new Sum(array, low, mid); Sum right = new Sum(array, mid, high); left.fork(); long rightans = right.compute(); long leftans = left.join(); join return leftans + rightans; zadanie jest wystarczająco małe fork 26 Fork/Join: RecursiveTask

Wywołanie RecursiveTask 27 Tablica liczb do zsumowania: int[] array = /*...*/; Z użyciem puli common: Long sum = ForkJoinPool.commonPool().invoke( new Sum(array, 0, array.length)); Z użyciem własnej puli wątków: ForkJoinPool pool = new ForkJoinPool(4); pool.invoke(new Sum(array, 0, array.length));

28 Pytania?