Glassfish + wątki

56 views
Skip to first unread message

nutysy

unread,
Dec 4, 2009, 4:41:51 AM12/4/09
to Lublin Java User Group (Lublin JUG)
Cześć, czy ktoś z Was miał może do czynienia z programowaniem zadań
cyklicznych na Glassfish'u ?

G.

unread,
Dec 4, 2009, 5:12:42 AM12/4/09
to Lublin Java User Group (Lublin JUG)


On 4 Gru, 10:41, nutysy <jaroslaw.las...@gmail.com> wrote:
> Cześć, czy ktoś z Was miał może do czynienia z programowaniem zadań
> cyklicznych na Glassfish'u ?

Czy mógłbyś uszczegółowić pytanie lub problem? Czy to jest coś co
dotyczy dokładnie Glassfisha czy też ogólne pytanie dotyczące "fredów"
na serwerach aplikacji?

Jarosław Łaszcz

unread,
Dec 4, 2009, 5:14:52 AM12/4/09
to lubli...@googlegroups.com
Raczej pytam ogólnie.

slawek sobotka

unread,
Dec 4, 2009, 5:25:06 AM12/4/09
to lubli...@googlegroups.com
Glassfisha nie uzywalem wiec nie wiem czy i jakie mechnizmy
skedżulingu dostarcza (jezeli jedynie standardowe dla jee to są one
mizerne).
Z tego co ludzie mówią to dobry skedżuling to kwarcowy skedżuling:
http://www.quartz-scheduler.org/

Pierwsza z brzegu integracja:
http://wiki.glassfish.java.net/Wiki.jsp?page=QuartzGlassFish

Sławomir Sobótka
http://art-of-software.blogspot.com

Maciej Zubala

unread,
Dec 4, 2009, 5:39:33 AM12/4/09
to lubli...@googlegroups.com
W dniu 4 grudnia 2009 11:14 użytkownik Jarosław Łaszcz
<jarosla...@gmail.com> napisał:
> Raczej pytam ogólnie.
>

W projekatch, które widziałem do schedulingu stosowano albo quartza
albo timery ejb3. Oba rozwiązania dawały radę. Jeśli chodzi o wątki i
przetwarzanie asynchroniczne, to pracowałem z jednym rozwiązaniem
opartym o JMS i też nie było żadnych niespodzianek.

--
Maciej Zubala
QDev - jakość oprogramowania
http://www.qdev.com.pl

G.

unread,
Dec 4, 2009, 5:41:07 AM12/4/09
to Lublin Java User Group (Lublin JUG)
> Z tego co ludzie mówią to dobry skedżuling to kwarcowy skedżuling:http://www.quartz-scheduler.org/

Dokładnie do tego samogo dążyłem. Polecam Quartz'a: http://www.opensymphony.com/quartz/.
Sprawdzony w bojach - działa i przeciwności do innych jest prawdziwie
wielowątkowy.

G.

slawek sobotka

unread,
Dec 4, 2009, 6:02:27 AM12/4/09
to lubli...@googlegroups.com
> W projekatch, które widziałem do schedulingu stosowano albo quartza
> albo timery ejb3. Oba rozwiązania dawały radę.

Timer EJB daje radę przy prostych planach ponieważ jego API jest
bardzo "podstawowe". Do tego w standardzie np do zainicjalizowania
samego timera trzeba sie nagimnastykować;P
Pytanie czy warto wchodzić w bardziej złożona api jakiejs zewnatrznej
biblioteki?
Decyzja powiedziałbym strategiczna... z czasem pojawia sie plany
bardziej złożone i używanie Timera będzie wiązało się z bólem. Do tego
nikt nie podejmie decyzji przepisania - bo działa;P

> Jeśli chodzi o wątki i
> przetwarzanie asynchroniczne, to pracowałem z jednym rozwiązaniem
> opartym o JMS i też nie było żadnych niespodzianek.

Ogólnie to używanie własnych wątków w aplikacjach na serwerze JEE jest
błędem w sztuce. Zależnie od servera posypie się w mniej lub bardziej
finezyjny sposób. No albo sie nie posypie i na jakimś konkretnym
serverze będzie działać:)
Wątkami zajmuje sie "platforma" a developer korporacyjny nie musi nic
o nich nawet wiedzieć;P

Co do JMS to dodam ciekawostkę, że można na niektórych serverach
wymusić istnienie kilku instancji danego Message Driven Beana
podłączonego do kolejki/topiku i każdą z nich przypisać do rdzenia
procesora aby osiągnąć wydajne asynchroniczne przetwarzanie
komunikatów.


Sławomir Sobótka
http://art-of-software.blogspot.com

walde...@googlemail.com

unread,
Dec 5, 2009, 9:38:07 AM12/5/09
to Lublin Java User Group (Lublin JUG)
On Dec 4, 12:02 pm, slawek sobotka <sso...@gmail.com> wrote:
> > Jeśli chodzi o wątki i
> > przetwarzanie asynchroniczne, to pracowałem z jednym rozwiązaniem
> > opartym o JMS i też nie było żadnych niespodzianek.
>
> Ogólnie to używanie własnych wątków w aplikacjach na serwerze JEE jest
> błędem w sztuce. Zależnie od servera posypie się w mniej lub bardziej
> finezyjny sposób. No albo sie nie posypie i na jakimś konkretnym
> serverze będzie działać:)
> Wątkami zajmuje sie "platforma" a developer korporacyjny nie musi nic
> o nich nawet wiedzieć;P

Cześć,

Sławek - pozwolę sobie nie zgodzić się z tym "używanie własnych wątków
w JEE jest błędem w sztuce" (nazwałbym tak naginanie JMS do tego
celu). Serwer aplikacyjny - jak to kontener - nakłada dodatkowe
ograniczenia (w skrócie: związane z ochroną zasobów serwera oraz
zarządzaniem kontekstami JNDI, transakcyjnym, czy security), stąd
_bezpośrednie_ użycie mechanizmów Java SE jest niezalecane. Od ok. 6
lat znane jest Work Manager API stworzone przez BEA i IBM i
implementowane przez WebLogic i WebSphere (co do innych to trzeba
sprawdzić). API jest proste, ale IMHO wystarczy do realizacji
większości scenariuszy zrównoleglania zadań po stronie serwera
aplikacyjnego (np. logiki wykonywanej w ramach servlet'ów czy EJB -
także w ramach bean'ów Spring, bo "opakowanie" tego API jest
udostępniane także przez Spring Framework).
Typowy scenariusz, często potrzebny w praktyce, to możliwość podziału
logiki przetwarzającej żądanie (np. HTTP request) na kilka stosunkowo
niezależnych i wykonywanych równolegle zadań, których wyniki wykonania
składają się na odpowiedź (HTTP response). Przy dzisiejszym sprzęcie
serwerowym (wiele CPU, wiele core per CPU, wiele wątków per core)
można znacznie (i niskim kosztem) podnieść wydajność wielu aplikacji
serwerowych. Np. dla webowych dosyć łatwo jest podzielić kod
generujący stronę na n podzadań i każde z nich wykonać równolegle, a
potem wygenerować stronę.

Zgoda, że EJB znacznie uprościło sytuację i w wielu aplikacjach w
dużym stopniu zwolniło deweloperów korporacyjnych od myślenia o
wątkach, ale potrzeba podziału większego zadania serwerowego na
mniejsze (co niemal zawsze oznacza potrzebę samodzielnego zarządzania
wątkami) pojawiła się niemal od razu. Wraz z JDK5/6
(java.util.concurrent) potrzeba czegoś podobnego (najlepiej
identycznego) po stronie Java EE też wzrosła - taki jest zresztą cel
Concurrency Utilities for Java EE - JSR 236 i 237. Póki co powinno
wystarczyć Work Manager API. JMS do tego celu to overkill...

Miałem przyjemność zademonstrować jak to działa podczas ostatnich Java
Developers Days (http://09.jdd.org.pl) i trochę to opisałem (http://
jdn.pl/node/1854). Powoli ogarniam się z robotą i postaram się wkrótce
opublikować na blogu kod przykładów demonstrujących to API...

Miałbym też uwagę do Quartz'a, że z tego co wiem (i słyszę od
Klientów), to Quartz nie używa mechanizmów wątkowych serwera
aplikacyjnego, więc w takim środowisku niesie te same ryzyka co
samodzielne zarządzanie wątkami (serwer aplikacyjny o wątkach Quartz'a
nie wie, więc nimi nie zarządza, itd)...

Moje trzy grosze...

Pozdrawiam,
Waldek Kot

PS
To z tym przypisywaniem MDB do core'ów to jest chyba to czego
deweloper korporacyjny nie powinien wiedzieć - takie rzeczy w dobie
wirtualizacji ??? ;-))

slawek sobotka

unread,
Dec 5, 2009, 6:34:28 PM12/5/09
to lubli...@googlegroups.com
Dzięki za wskazanie bibliotek do wątków - na pewno się przyda.
Co do przypisywania fasolek napędzanych komunikatami do jajek
procesora to oczywiście nie powinno to byc zmartwienie developera. A
ludzie robią rozne rzeczy, sami wiecie;P

Paweł Janusz

unread,
Dec 6, 2009, 1:56:13 AM12/6/09
to lubli...@googlegroups.com
Czesc


No właśnie czasami jest tak, że developerzy muszą tak na prawdę zestawić i zintegrować środowisko. Nie podzielam tego, ale taki jest świat.

Pawel

 

walde...@googlemail.com

unread,
Dec 6, 2009, 12:15:04 PM12/6/09
to Lublin Java User Group (Lublin JUG)
On Dec 6, 7:56 am, Paweł Janusz <czuj...@gmail.com> wrote:
> No właśnie czasami jest tak, że developerzy muszą tak na prawdę zestawić i
> zintegrować środowisko. Nie podzielam tego, ale taki jest świat.

Pewnie, że tak bywa i swoją drogą dobrze żeby deweloperzy wiedzieli
coś nt. administracji (i odwrotnie) - konfiguracji sieci, storage'u,
security, wirtualizacji, sposobu diagnozowania problemów, itp.

Co do przypisywania core do MDB, to przyznam, że też nie jestem
pewien, czy faktycznie takie coś jest możliwe ? Można przypisać cały
proces JVM do konkretnych rdzeni/CPU (np. w Linuxach użyć polecenia
numactl - co ma zresztą sens tylko na maszynach z architekturą NUMA, z
tzw. commodity, to miewają ją Intel Xeon 55xx, czy AMD Opteron), ale o
tym, żeby w ramach jednego JVM wybrane wątki (tu: MDB) można było
przypiąć do rdzenia, to nie słyszałem. Sławek - daj proszę jakiegoś
linka do opisu tego o czym wspominasz.

Nawet jeśli byłoby to możliwe, to też nie zawsze musi dawać dobre
wyniki jeśli chodzi o wydajność - jak rozumiem to chodzi tu o to, że
do wykonywania kodu MDB dedykujemy wybrane rdzenie CPU, a pozostały
kod wykonywany jest przez resztę core'ów, co pozwala niezakłócać
wykonywania MDB przez wykonywanie innych operacji oraz lepiej
wykorzystać cache CPU (albo przynajmniej nie "brudzić" tych cache,
rozsynchronozwać, itp.) ? Oba cele są bardzo specyficzne dla użytych
OS i JVM - np. nowe wersje JVM rozpoznają architekturę maszyny i
wykonują kod (szczególnie alokację pamięci oraz przypisanie wątków
wykonujących kod Java i wątków GC) bardziej optymalnie (są NUMA-aware,
NUMA = Non-Unified Memory Access). Podobnie zresztą (choć na wyższym
poziomie abstrakcji) robią to niektóre serwery aplikacyjne z
przypisaniem transakcji, czy połączeń JDBC do wątku (thread
affinity).

To podejście z przypisaniem MDB do core zakłada również, że
przyspieszy się wykonywanie kodu przetwarzającego komunikat z JMS. Z
tym, że bez zrównoleglenia kod ten wykona się w dużym stopniu na
jednym wątku (powiedziałbym, że większość - choć nie wszystkie ;-) -
serwerów aplikacyjnych wykona go w całości na jednym wątku). No i
wykona się sekwencyjnie. Dzieląc kod w MDB na wiele równolegle
wykonywanych wątków i pozwalając je wykonać na wielu CPU/core/hardware-
thread można osiągnąć znacznie lepsze wyniki niż przypisując MDB do
core.

A jeśli chce się zagwarantować, że dany komponent (tu MDB) będzie mieć
zawsze wyższy priorytet dostępu do wątków wykonawczych, to tu też z
pomocą przychodzi Work Manager - choć tym razem nie jako API, ale jako
zasób konfigurowalny na poziomie serwera aplikacyjnego. Konfigurowalny
poprzez mechanizm sterowania QoS (Quality of Service) Work Manager'ów
(czyli też zarządzanych przez nie wątków). W ramach takiego QoS można
np. zdefiniować, że Work Manager ma zagwarantowane pewne minimum
wątków wykonawczych (albo odwrotnie - że pewnej liczby wątków dany
komponent nie przekroczy. Można pójść jeszcze dalej i skonfigurować że
komponent - Work Manager - nie przyjmie więcej zadań niż podana
liczba, a nadmiarowe zadania będą odrzucone - w przypadku klastra
zwykle oznacza to, że inna instancja serwera aplikacyjnego obsłuży
takie zadanie). Albo, że w procesie scheduling'u wątki danego Work
Manager'a dostaną większy udział czasu CPU. Albo, że wątki mają być
harmonogramowane w reżimie czasu rzeczywistego, z określonym celem na
czas odpowiedzi. I tym podobne. Takie QoS są wskazówkami (hint) dla
scheduler'a serwera aplikacyjnego, pomagające mu wybrać które wątki i
w jaki sposób ma obsłużyć (w tym "dawać" im zasoby w rodzaju czas
CPU)... Takie sterowanie QoS Work Manager'ów dostępne w WebLogic
Server też opiszę na blogu (http://jdn.pl/blog/88)...

Pozdrawiam,
Waldek Kot

PS
Trochę off-topic i prywaty ;-):
tak jak wspomniałem - sporo zależy też sprzętu (core jednego CPU nie
jest równy core innego CPU), a także od OS (a w przypadku
wirtualizacji, także od scheduler'a hypervisor'a). Niestety, ale OS
które są powszechnie używane nie rozumieją tego co robi JVM i obie
strony (tj. OS i JVM) nie koordynują swojego działania (nawet
przeszkadzają sobie). To jest także jedna z motywacji dlaczego w BEA/
Oracle'u tworzymy wirtualizację JVM, czyli technologię pozwalającą
uruchamiać aplikacje Java bez klasycznego systemu operacyjnego
(którego JVM dla serwerowych aplikacji Java - takich jak Java EE - tak
naprawdę też nie potrzebuje). Jedną z ciekawych optymalizacji które
pojawią się w przyszłości w ramach wirtualizacji JVM, to zgranie
scheduler'a JVM ze scheduler'em hypervisora. Jeden "wie" wszystko o
wątkach na poziomie JVM, ich blokadach, charakterystyce wykonywania,
itd. Drugi "wie" jak wygląda sprzęt "pod spodem". Inteligentna
komunikacja pomiędzy obydwoma, daje spory potencjał na lepszą
wydajność, choćby poprzez minimalizowanie przestojów wątków na
blokadach (w aplikacjach serwerowych to dla wydajności kluczowa rzecz,
zwłaszcza mając wkrótce setki core'ów w sprzęcie pod spodem)...

Marek Karwacki

unread,
Dec 6, 2009, 2:01:24 PM12/6/09
to lubli...@googlegroups.com
W dniu 6 grudnia 2009 18:15 użytkownik walde...@googlemail.com <walde...@googlemail.com> napisał:

Z tym, że bez zrównoleglenia kod ten wykona się w dużym stopniu na
jednym wątku (powiedziałbym, że większość - choć nie wszystkie ;-) -
serwerów aplikacyjnych wykona go w całości na jednym wątku). No i
wykona się sekwencyjnie.

Cześć,

Mógłbyś napisać coś więcej o tym samoczynnym zrównolegleniu kodu?
Domyślam się, że działa to tylko dla pewnej klasy problemów.
Czy działa to na zasadzie np. zrównoleglania pętli z niezależnymi iteracjami? Samo rozpozna takie miejsca w kodzie bez żadnych dodatkowych znaczników?

Minusem aktualnego Sun JVM w zastosowaniach HPC i prawie HPC ;) (o takich chyba napisałeś) jest sposób zarządzania pamięcią.
Mam na myśli tzw cache-oblivious struktury danych. Przez aktualny GC ciężko określić czy to co chcemy będzie w biężącej chwili w cache.
Może to nie jest popularny problem w biznesie i nie opłaca się robić obsługi tego w JVM. Nie testowałem tutaj JRockit, może tam jest to lepiej rozwiązane. Być może rozwiązaniem już by było możliwość ręcznego sterowania GC.

Apropo wykorzystania rdzeni CPU. Wiesz może czy są plany wykorzystania też mocy GPU?


Pozdrawiam,
Marek

walde...@googlemail.com

unread,
Dec 6, 2009, 4:03:16 PM12/6/09
to Lublin Java User Group (Lublin JUG)
On Dec 6, 8:01 pm, Marek Karwacki <marek.karwa...@gmail.com> wrote:
> Mógłbyś napisać coś więcej o tym samoczynnym zrównolegleniu kodu?
> Domyślam się, że działa to tylko dla pewnej klasy problemów.
> Czy działa to na zasadzie np. zrównoleglania pętli z niezależnymi
> iteracjami? Samo rozpozna takie miejsca w kodzie bez żadnych dodatkowych
> znaczników?

Cześć,

Tu bardziej niż samoczynne zrównoleglanie kodu chodziło mi o to, że
pewne operacje (szczególnie I/O - kontakt do zewnętrznych systemów czy
baz danych) w serwerze aplikacyjnym można zrobić w ten sposób, że będą
wykonywać się asynchronicznie, czyli po wysłaniu żądania oczekiwanie
na odpowiedź nie będzie blokować wątku wykonawczego, który będzie mógł
powędrować z powrotem do puli, gdzie posłuży obsłudze innego żądania.
W ten sposób przepustowość serwera (aplikacji na nim) jest większa...

To o czym Ty piszesz, to jeden poziom niżej, czyli JVM. Optymalizacje
z "rozwijaniem pętli" są robione przez JVM (akurat ta myślę, że jest
zarówno w HotSpot, jak i w JRockit), choć jeszcze nie ma rozbijania
interacji na niezależne równolegle wykonywane "wątki" (i skala - czyli
"rozmiar" pętli - nie taka jak w HPC). To wymaga analizy statycznej
kodu wewnątrz iteracji, a analiza statyczna dopiero przebija się do
JVM (z racji tego jak działają typowe JVM ta analiza musi być
wykonywana w ramach JIT, a tu są ograniczenia czasowe). Niestety, do
bytecode'u nie trafiają informacje z czasu kompilacji, a i metadane w
postaci adnotacji są dosyć ograniczone (bardzo liczę na Java 7, gdzie
miejsc do wstawienia adnotacji będzie więcej - choć chyba jeszcze się
nie zdecydują na wprowadzenie adnotowania bloków instrukcji ani
pojedynczych instrukcji, a to byłby idealny mechanizm pomagający
optymalizatorowi kodu w JVM)... Takie rozwijanie pętli trzeba też
oszacować, czy się opłaca robić - więcej nadziei pokładam w ręcznym
przekazywaniu tych informacji przez dewelopera (ewentualnie przez
narzędzia w rodzaju IDE czy profiler) niż samodzielne ich wyłuskiwanie
przez kompilator bytecode'u w JVM - on i tak ma dosyć utrudnione
zadanie (i reżim czasowy w którym musi zdążyć wygenerować w miarę
zoptymalizowany kod maszynowy), bo bytecode (jako że robiony 11 lat
temu i na inne potrzeby) jest dosyć "surowy" - dla przykładu nawet
informacje o tym czy i gdzie jest pętla kompilator bytecode'u musi
odtwarzać, bo bytecode ich nie zawiera...

> Minusem aktualnego Sun JVM w zastosowaniach HPC i prawie HPC ;) (o takich
> chyba napisałeś) jest sposób zarządzania pamięcią.
> Mam na myśli tzw cache-oblivious struktury danych. Przez aktualny GC ciężko
> określić czy to co chcemy będzie w biężącej chwili w cache.

GC tu chyba niewiele wnosi (większość języków programowania ma GC,
począwszy od Lispa z lat 70-tych). Algorytmy cache-oblivious to jedno,
ale wcześniej przydałoby się trochę więcej możliwości sterowania na
poziomie cache - pamięć. Tu znowu "winnym" są mainstream'owe CPU (i
pewnie trochę swoje dokładają typowe OS, które - jak pisałem wcześniej
- nierozumieją struktur JVM w rodzaju Java heap, czy np. nie
odróżniają wątków wykonujących kod Java od wątków wykonujących GC). W
implementacji JRockit dla takiego IA64 (Itanium) rzeczy w rodzaju
spekulatywny odczyt danych, czy optymalizacje sterowane danymi
profilingowymi zbieranymi przez CPU (Profile Guided Optimizations) są
robione. Xeon'y ich nie mają (jeszcze ;-) ?). A życie (choćby Intel
Atom) pokazuje, że z ISA x86 jeszcze długo będziemy się zmagać. Tu też
metadane z poziomu języka programowania przeniesione do bytecode'u i
wykorzystywane przez optymalizator bardzo by się przydały...

W JRockit wiele optymalizacji jest robionych pod kątem typowych
struktur w rodzaju HashMap, czy TreeMap i te optymalizacje są dla
konkretnych rodzin CPU (np. Intel, AMD, Sparc), a czasem nawet modeli
CPU (Nehalem, Opteron, ...), z uwzględnieniem ich konkretnych
wielkości cache L1-L3, itd. Oczywiście HPC to trochę inne
architektury, HotSpot i JRockit są przeznaczone dla mainstream'owych
serwerów klasy commodity (x86). Wielkości cache tu używane nie są
wielkie (dopiero teraz pojawiają się mainstream'owe CPU z kilku(nasto)
megabajtowymi cache L3). Raczej więc chodzi o optymalizacje na
poziomie mikro niż gigabajtowych struktur danych. Z drugiej strony
JRockit od dawna dosyć regularnie jest wykorzystywany przez SGI (a ich
rynkiem jest HPC) do benchmarków na maszynach z tysiącami CPU i
Terabajtami RAM...

> Być może rozwiązaniem już by było możliwość ręcznego sterowania GC.

Tu z pomocą może przyjść RTSJ czy nawet bufory NIO. Choć dużą część
problemów typu soft-real time załatwia dobry deterministyczny GC, a
zaletą tego podejścia jest brak konieczności przepisywania aplikacji,
tak, by używała nowego API w rodzaju RTSJ (który jest mówiąc krótko
inną Javą).

> Apropo wykorzystania rdzeni CPU. Wiesz może czy są plany wykorzystania też
> mocy GPU?

Na pewno jest to sensowny pomysł, choć trzeba chyba poczekać na
upowszechnienie się serwerów w które włożono przyzwoite GPU (chicken-
egg problem do ponownego rozwiązania). Osobiście wątpię też, żeby
ktokolwiek inny niż Intel był w stanie popchnąć branżę w tę stronę (a
Larrabee się chyba znowu opóźni...) .
Sporo też jeszcze zostało do zrobienia w JVM, aby korzystały one z
instrukcji typu SIMD dostarczanych przez rozszerzenia w rodzaju SSE.
Często są one znacznie szybsze niż stosowe czy pochodzące z x87. A i
dodatkowe rejestry SSE (które są i szybkie, i pojemne, i jest ich
stosunkowo dużo) bardzo pomagają.

Pozdrawiam,
Waldek Kot

slawek sobotka

unread,
Dec 6, 2009, 4:38:51 PM12/6/09
to lubli...@googlegroups.com
Waldek, widzę, że jesteś "nieco" zorientowany w tym, co "siedzi pod
maską". Na prawdę robi to wrażenie.

Chciałbym zapytać odnośnie JSE, w kontekście zwykłej aplikacji
standalone - po prostu od jakiegoś czasu zastanawiam się tworzyć
pewien soft na starym, dobrym desktopie:)
Chodzi mi o wydajność, a dokładnie o wykorzystanie potencjału
wielordzeniowych procesorów. Wszystko w kontekście systemu Microsoftu.

Czy jeżeli w moim programiku będzie kilka wątków to czy zostaną
potencjalnie wykonanie równolegle na kilku rdzeniach?
Z tego co wiem to jeszcze jakiś czas temu pod HotSpot Suna dla Windows
obsługiwał wątki Javy "sztucznie". Czyli tak na prawdę po stronie
Windowsa był to jeden wątek (albo proces?), a JVM jedynie przełączał
swoje wewnętrzne wątki na ten jeden systemowy. Jeżeli tak, to OS nie
miał szans sobie tego rozłożyć na rdzenie.
Czy w dalszym ciągu tak to wygląda, a jeżeli tak to kiedy może się to zmienić?

Pytanie dosyć podstawowe, ale nie mogę od dłuższego czasu znaleźć
jasnej i jednoznacznej odpowiedzi.


z poważaniem
Sławek Sobótka
http://art-of-software.blogspot.com

Marek Karwacki

unread,
Dec 6, 2009, 4:39:07 PM12/6/09
to lubli...@googlegroups.com
Niestety, do bytecode'u  nie trafiają informacje z czasu kompilacji, a i metadane w
postaci adnotacji są dosyć ograniczone (bardzo liczę na Java 7, gdzie
miejsc do wstawienia adnotacji będzie więcej - choć chyba jeszcze się
nie zdecydują na wprowadzenie adnotowania bloków instrukcji ani
pojedynczych instrukcji, a to byłby idealny mechanizm pomagający
optymalizatorowi kodu w JVM)... Takie rozwijanie pętli trzeba też
oszacować, czy się opłaca robić - więcej nadziei pokładam w ręcznym
przekazywaniu tych informacji przez dewelopera (ewentualnie przez
narzędzia w rodzaju IDE czy profiler) niż samodzielne ich wyłuskiwanie
przez kompilator bytecode'u w JVM - on i tak ma dosyć utrudnione
zadanie

Jasne, choćby zrobić coś podobnego do dyrektyw z OpenMP dla C/Fortran ale jakby coś potrafiło samo nakładać takie dyrektywy to by było jeszcze lepiej
(zakładam, że mowa o równoległości "dla każdego")

GC tu chyba niewiele wnosi (większość języków programowania ma GC,
począwszy od Lispa z lat 70-tych). Algorytmy cache-oblivious to jedno,
ale wcześniej przydałoby się trochę więcej możliwości sterowania na
poziomie cache - pamięć. Tu znowu "winnym" są mainstream'owe CPU

Tak, bardziej winne jest CPU za to że nie można bezpośrednio sterować cache niż GC.
Założyłem, że CPU jest jaki jest i to wszystkie języki muszą się mu podporządkować.

 
W implementacji JRockit dla takiego IA64 (Itanium) rzeczy w rodzaju
spekulatywny odczyt danych, czy optymalizacje sterowane danymi
profilingowymi zbieranymi przez CPU (Profile Guided Optimizations) są
robione. Xeon'y ich nie mają (jeszcze ;-) ?).

Zachęciłeś mnie do JRockit :)

 

Na pewno jest to sensowny pomysł, choć trzeba chyba poczekać na
upowszechnienie się serwerów w które włożono przyzwoite GPU (chicken-
egg problem do ponownego rozwiązania). Osobiście wątpię też, żeby
ktokolwiek inny niż Intel był w stanie popchnąć branżę w tę stronę (a
Larrabee się chyba znowu opóźni...) .

Nvidia CUDA jest ostatnio coraz bardziej popularna na rynku HPC. W pewnych typach problemów wzrost wydajności nad CPU jest nawet rzędu 2.
Larrabee ma być bardziej uniwersalne ale wiem póki co o tym tylko tyle że się opóźni :)
 
Sporo też jeszcze zostało do zrobienia w JVM, aby korzystały one z
instrukcji typu SIMD dostarczanych przez rozszerzenia w rodzaju SSE.
Często są one znacznie szybsze niż stosowe czy pochodzące z x87. A i
dodatkowe rejestry SSE (które są i szybkie, i pojemne, i jest ich
stosunkowo dużo) bardzo pomagają.


Nie wiedziałem nawet, że JVM nie obsługuje SSE. To chyba nie jest trudne do implementacji gcc wspiera  wszystkie poziomy SSE.


Pozdrawiam,
Marek

walde...@googlemail.com

unread,
Dec 6, 2009, 8:41:10 PM12/6/09
to Lublin Java User Group (Lublin JUG)
On Dec 6, 10:38 pm, slawek sobotka <sso...@gmail.com> wrote:
> Czy jeżeli w moim programiku będzie kilka wątków to czy zostaną
> potencjalnie wykonanie równolegle na kilku rdzeniach?

Zarówno język Java, jak i mainstream'owe implementacje JVM (np.
HotSpot, czy JRockit) są od początku wielowątkowe - faktycznie był
czas, że JVM miały opcję używania tzw. green threads, mapujących wątki
Java na wątki OS (niekoniecznie 1:1), ale powodowało to więcej
problemów niż korzyści i zaprzestano tego podejścia. Wątki Java w JVM
mapują się jeden do jednego na wątki OS (w zasadzie są tym samym).
Skoro tak, to OS będzie je rozrzucać na to co mu daje sprzęt -
procesory (CPU), rdzenie (core) i sprzętowe wątki (wiele core ma
możliwość równoczesnego wykonywania kilku wątków naraz - żeby
skomplikować sprawę bardziej, to jest jeszcze coś takiego jak
Symmetric Multithreading - choćby znany intelowski Hyperthreading - to
też w sumie daje 2 równocześnie wykonujące się wątki).

Systemy operacyjne pokazują 1 proces JVM (np. w Windows będzie to
java.exe). Ale w ramach tego procesu działa wiele wątków (nawet
dziesiątki tysięcy - choć tu każdy OS ma swoje limity, także są limity
"sprzętowe", choćby to, że każdy wątek zajmuje określoną ilość RAM).

To co de facto harmonogramuje OS (np. Linux, czy Windows) do wykonania
na CPU/core to wątki, nie procesy... Oczywiście, na OS może działać
równocześnie wiele procesów JVM - po prostu OS harmonogramuje wątki
pochodzące ze wszystkich procesów (w tym procesów JVM).

Proces JVM używa wiele wątków - nawet gdy aplikacja jest jednowątkowa
(czyli nie używa java.lang.Thread, Java agent'ów, itp.). Np. w JVM,
garbage collector działa na innych wątkach niż aplikacja. Podobnie
różnego rodzaju wewnętrzne zadania JVM są wykonywane na oddzielnych
wątkach (np. JIT, generator kodu maszynowego, kod obsługi finalize,
czy referencji Weak/Soft/...). Można się o tym przekonać samodzielnie
- wystarczy w oknie z uruchomioną aplikacją Java wcisnąć CTRL+Break
(czyli zrobić Thread Dump - zrzut stanu wątków). Zarówno HotSpot, jak
i JRockit pokazują kilkanaście (10-15) wątków. Potencjalnie każdy z
nich może działać na innym core/CPU (i korzystają z tego algorytmy GC
typu parallel) - o tym decyduje OS.

Także w Windows Taks Manager w zakładce "Processes" można dodać
kolumnę "Threads" - widać będzie, że proces java.exe ma minimum
kilkanaście wątków. W przypadku JVM z serwerem aplikacyjnym może być
tam widoczne i kilkaset wątków (choć zwykle jest to kilkadziesiąt). Na
przykład domyślnie maksymalny rozmiar puli wątków w WebLogic Server to
65536 (co jest przesadą na dzisiejszych typowych maszynach
serwerowych).

Co do równomierności rozłożenia wątków, to zależy to od OS. Można
przyjąć ogólne założenie, że wątki będą rozkładane tak, żeby wszystkie
CPU/core były zajęte.

A zatem - jak najbardziej warto tworzyć wielowątkowy kod we własnych
aplikacjach Java. Zarówno po stronie desktop, jak i po stronie serwer.
JDK 5 i 6 mają przyzwoite wsparcie dla bardziej wyrafinowanej
współbieżności w postaci java.util.concurrent.

Pozdrawiam,
Waldek Kot

PS
Na Windows, zamiast standardowego Task Manager'a polecam Process
Explorer do ściągnięcia z www.sysinternals.com. Podaje znacznie więcej
informacji.

walde...@googlemail.com

unread,
Dec 6, 2009, 8:48:36 PM12/6/09
to Lublin Java User Group (Lublin JUG)
On Dec 6, 10:39 pm, Marek Karwacki <marek.karwa...@gmail.com> wrote:
> > Sporo też jeszcze zostało do zrobienia w JVM, aby korzystały one z
> > instrukcji typu SIMD dostarczanych przez rozszerzenia w rodzaju SSE.
> > Często są one znacznie szybsze niż stosowe czy pochodzące z x87. A i
> > dodatkowe rejestry SSE (które są i szybkie, i pojemne, i jest ich
> > stosunkowo dużo) bardzo pomagają.
>
> Nie wiedziałem nawet, że JVM nie obsługuje SSE. To chyba nie jest trudne do
> implementacji gcc wspiera  wszystkie poziomy SSE.

To znaczy obsługuje (JVM dla Unix'ów też są kompilowane gcc, wersje
windowsowe raczej kompilatorem z Visual Studio) i kod JVM korzysta z
tych optymalizacji. Chodziło mi raczej o to, że pewne zadania JVM (np.
GC) mogą działać szybciej jeśli explicite do ich implementacji użyje
się SSE. Podobnie, znajdujący się w JVM kompilator JIT bytecode'u Java
do kodu maszynowego mógłby produkować bardziej wydajny kod maszynowy
zawierający SSE.

Jedyną wadą jest podniesienie minimalnych wymagań na sprzęt - Pentium
IV i wyższe.

Notabene ten kompilator JIT ma w dużym stopniu te same optymalizacje
co gcc...

Pozdrawiam,
Waldek Kot

slawek sobotka

unread,
Dec 7, 2009, 5:54:48 AM12/7/09
to lubli...@googlegroups.com
Waldku, dziękuję za odpowiedź i chylę czoła przed ekspercką wiedzą.

Marek Karwacki

unread,
Dec 7, 2009, 7:42:46 AM12/7/09
to lubli...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages