Warsztat.GD

Programowanie => Projektowanie kodu => Wątek zaczęty przez: defeatomb w Kwiecień 26, 2007, 16:41:22

Tytuł: Wątki
Wiadomość wysłana przez: defeatomb w Kwiecień 26, 2007, 16:41:22
Mam pytanie. Otóż wiele osób twierdzi, że pisanie aplikacji wielowątkowych to ciężka rzecz itp.
Z tego co zrozumiałem to chodzi o synchronizację danych. A co jeśli zastosuje mechanizm, że
każdy wątek zamiast na własną rękę modyfikować dane w pamięci będzie uruchamiał np. prockę
Exec() z odpowiednimi parametrami. Ta zaś działa na zasadzie kolejkowania. Exec dodaje polecenie
do stosu, a polecenia ze stosu są niezależnie wykonywane przez inny wątek który ma prawo do
modyfikowania pamięci i wykonuje jedno poleceni ze stosu na raz. Każde odwołanie z zewnątrz
do danych przechodziło by przez Execa.

Może to trochę zamotane, ale wierzę w was ;D
Tytuł: Odp: Wątki
Wiadomość wysłana przez: Reg w Kwiecień 26, 2007, 16:54:23
No dobra, to jest jakieś rozwiązanie. Wtedy komunikacja między wątkami ograniczałaby się do wysyłania i pobierania komunikatów z kolejki, na której odbywała by się też synchronizacja. Ale niestety programowanie wielowątkowe nie jest takie proste i nie da się go sprowadzić do jednego słusznego modelu, bo z wielu względów (choćby wydajnościowych) w różnych sytuacjach stosuje się różne rozwiązania. Aczkolwiek owszem, są pewne wzorce które warto znać i stosować, np. producent-konsument, czytelnicy-i-pisarze czy też monitor. Poczytaj o tym.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: bies w Kwiecień 26, 2007, 17:57:12
Mam pytanie. Otóż wiele osób twierdzi, że pisanie aplikacji wielowątkowych to ciężka rzecz itp.
Z tego co zrozumiałem to chodzi o synchronizację danych. A co jeśli zastosuje mechanizm, że
każdy wątek zamiast na własną rękę modyfikować dane w pamięci będzie uruchamiał np. prockę
Exec() z odpowiednimi parametrami. Ta zaś działa na zasadzie kolejkowania. Exec dodaje polecenie
do stosu, a polecenia ze stosu są niezależnie wykonywane przez inny wątek który ma prawo do
modyfikowania pamięci i wykonuje jedno poleceni ze stosu na raz. Każde odwołanie z zewnątrz
do danych przechodziło by przez Execa.

Może to trochę zamotane, ale wierzę w was ;D
Brawo, jesteś na bardzo dobrej drodze. Teraz przemyśl wiele takich funkcji Exec() i wiele kolejek ułożonych w strumień. Poczytaj o przetwarzaniu strumieniowym [1] - właśnie tak powinno się pisać bardzo wydajne systemy wielowątkowe. Coś trudniejszego to użycie algorytmów i struktur lock-free zamiast prostych elementów synchronizacji (muteksy, monitory itp.). Przejrzyj archiwum pl.comp.lang.c - ostatnio było tam sporo na ten temat.

[1] http://en.wikipedia.org/wiki/Stream_processing

// edit
Poprawka cytatu -- nie miałem zamiaru cytować Rega.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: defeatomb w Kwiecień 27, 2007, 04:00:02
No dobra, to jest jakieś rozwiązanie. Wtedy komunikacja między wątkami ograniczałaby się do wysyłania i pobierania komunikatów z kolejki, na której odbywała by się też synchronizacja. Ale niestety programowanie wielowątkowe nie jest takie proste i nie da się go sprowadzić do jednego słusznego modelu, bo z wielu względów (choćby wydajnościowych) w różnych sytuacjach stosuje się różne rozwiązania. Aczkolwiek owszem, są pewne wzorce które warto znać i stosować, np. producent-konsument, czytelnicy-i-pisarze czy też monitor. Poczytaj o tym.

Zdaję sobie sprawę, że nie da się sprowadzić wielowątkowości do jednego modelu.
Generalnie moim celem było sprawdzenie czy obieram odpowiedni kierunek czy nie.

Dzięki też za materiały i podpowiedzi.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: infernus w Kwiecień 28, 2007, 14:48:12
Jaki będzie zysk z takiego rozwiązania? Bo wątpie by zaowocowało to jakimkolwiek wzrostem wydajności. Wywolywanie funkcji wewnątrz aplikacji z pewnoscia jest szybsze niz otwieranie nowego programu. Narzut może byc ogromny! Takie rozwiązanie napewno bedzie wolniejsze od standardowego.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: mINA87 w Kwiecień 28, 2007, 14:54:26
Jaki będzie zysk z takiego rozwiązania? Bo wątpie by zaowocowało to jakimkolwiek wzrostem wydajności. Wywolywanie funkcji wewnątrz aplikacji z pewnoscia jest szybsze niz otwieranie nowego programu. Narzut może byc ogromny! Takie rozwiązanie napewno bedzie wolniejsze od standardowego.

O czym Ty człowieku rozmawiasz? O RPC czy o wielowątkowości? Sprecyzuj się i używaj poprawnych pojęć.
Twierdzić możesz sobie co chcesz, ale okazuje się że przez wzgląd na synchroniczność niektórych operacji warto jest porozdzielać zadania na wątki i przyrost wydajności będzie, bo system sobie poradzi ładnie z obydwoma wątkami a na platformach wielordzeniowych wystąpi równoczesne wykonywanie wątków - chyba nie powiesz, że to będzie szybsze od standardu.
A ogólnie rzecz biorąc czasem system wątkowy czy RPC jest wymuszony przez architekturę całości systemu i tyle.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: defeatomb w Kwiecień 28, 2007, 19:00:59
Exec to przykładowa nazwa funkcji ;E a nie z WinAPI exec, że uruchamia inny proces.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: Reg w Kwiecień 30, 2007, 16:46:04
bies: Dzięki za cenne rady i poparcie dla mojego rozwoju, ale to nie mnie trzeba tutaj odpowiadać bo nie ja zadałem pytanie ;P
Tytuł: Odp: Wątki
Wiadomość wysłana przez: bies w Kwiecień 30, 2007, 17:37:44
bies: Dzięki za cenne rady i poparcie dla mojego rozwoju, ale to nie mnie trzeba tutaj odpowiadać bo nie ja zadałem pytanie ;P
Ech, pomyliłem cytat -- już poprawiam.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: Esidar w Maj 01, 2007, 15:09:01
Poczytaj o przetwarzaniu strumieniowym [1] - właśnie tak powinno się pisać bardzo wydajne systemy wielowątkowe.
[1] http://en.wikipedia.org/wiki/Stream_processing

Stream processing zakłada że ciąg przetwarzanych danych jest przewidywalny. W ten sposób
można w prosty sposób przetwarzać np. dźwięk lub obraz. Dzieli się je na mniejsze bloki i przetwarza
na różnych wątkach.

Gdy mówimy o wielowątkowości np. w grach, to tam jest ciężej o takie dane. W grach jest więcej danych
zależnych od siebie i opartych o zdarzenia i tam ciągle potrzeba dużo przetważać liniowo. Do tego dochodzi
duża różnorodność danych.
Model Stream processing  jest użyty w jednostkach SPU w PS3. Ale przez to ich użycie w grach jest niezwykle trudne
(każdy układ ma tylko 256kB gdyż idea opiera się na intensywnym przetwarzaniu nie wielkiej ilości przewidywalnych
danych wejściowych).

Jak wspomniał Reg, programowanie wielowątkowe nie jest proste i nie da się sprowadzić do jednego słusznego modelu.
Najczęściej jest potrzebne użycie kilku modeli np. opartego o zdarzenia i opartego o ciągi danych.

Inny problem to czy przydzielać zadania dynamicznie, czy przydzielić wcześniej na stałe. Obydwa rozwiązania mają swoje
wady i zalety i też nie ma tego jedynego słusznego.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: bies w Maj 14, 2007, 20:00:18
Poczytaj o przetwarzaniu strumieniowym [1] - właśnie tak powinno się pisać bardzo wydajne systemy wielowątkowe.
[1] http://en.wikipedia.org/wiki/Stream_processing

Stream processing zakłada że ciąg przetwarzanych danych jest przewidywalny. W ten sposób
można w prosty sposób przetwarzać np. dźwięk lub obraz. Dzieli się je na mniejsze bloki i przetwarza
na różnych wątkach.

Gdy mówimy o wielowątkowości np. w grach, to tam jest ciężej o takie dane. W grach jest więcej danych
zależnych od siebie i opartych o zdarzenia i tam ciągle potrzeba dużo przetważać liniowo. Do tego dochodzi
duża różnorodność danych.
W grach pewnie tak, w serwerach gier juz niekoniecznie. ;)

Jak wspomniał Reg, programowanie wielowątkowe nie jest proste i nie da się sprowadzić do jednego słusznego modelu.
Najczęściej jest potrzebne użycie kilku modeli np. opartego o zdarzenia i opartego o ciągi danych.
Model oparty o zdarzenia powinien dobrze przekształcać się do strumieni -- patrz IOCompletionPorts.

Inny problem to czy przydzielać zadania dynamicznie, czy przydzielić wcześniej na stałe. Obydwa rozwiązania mają swoje
wady i zalety i też nie ma tego jedynego słusznego.
Prawie zawsze dynamicznie. Statycznie nie przewidzisz dobrze rozkładu obciążenia i będziesz miał kiepską wydajność.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: Esidar w Maj 14, 2007, 21:17:48
Prawie zawsze dynamicznie. Statycznie nie przewidzisz dobrze rozkładu obciążenia i będziesz miał kiepską wydajność.
Prawie robi różnicę ;) Znowu pewnie lepiej będzie użyć modelu mieszanego.
Przykład: 6 procesorów DSP (np. w PS3). Każdy posiada 256kB pamięci. Przydzielając zadanie trzeba najpierw załadować
kod dotyczący zadania i dane, do procesora. Jeśli wiesz, że wśród 200 zadań które się mogą pojawić, 100 z nich
będzie operować na tych samych danych (np. animacja 100 postaci opartych na tym samym meshu), to możesz
statycznie przeznaczyć 3-4 procesory na te zadania, załadować do nich dane i kod tylko raz, a 2 pozostałe procesory przeznaczyć
na zadania nie tak łatwo przewidywalne. Nawet jeśli 10 kolejnych zadań nie będzie dotyczyć tych 3-4 procesorów, to lepiej je
"przemęczyć" przez te 2 procesory niż robić "switch state'y". Przy 100 zadaniach, może switch state nie zrobi różnicy ale przy
10,000 zrobi.

Tytuł: Odp: Wątki
Wiadomość wysłana przez: bies w Maj 14, 2007, 22:18:34
"switch state'y"
Zdefiniuj proszę -- nie znam PS3.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: Esidar w Maj 14, 2007, 23:47:25
Układ CELL w PS3 ma 6 procesorów DSP. Każdy z nich posiada własne 256kB i nie ma dostępu do pamięci głównej (przynajmniej nie bezpośrednio z poziomu samego procesora). Rozdzielaniem zadań zajmuje się główny procesor PowerPC. Problem polega na tym, że przydzielając nowe zadanie, główny procesor, musi przesłać do procesora DSP kod realizujący to zadanie oraz dane dla tego zadania. Switch state, następuje właśnie wtedy gdy przydzielając nowe zadanie które jest innego rodzaju niż poprzednie, do procesora DSP trzeba na nowo przesłać kod nowego zadania i nowe dane. Przesyłanie 256kB danych i kodu może zająć więcej czasu niż wykonanie tego zadania więc trzeba tego unikać. No i czas wykonywania powinien być w miarę przewidywalny aby wybrać odpowiednią technikę

W zależności od charakteru programu i zadań jakie wykonuje trzeba używać różnych technik minimalizujących ilość przesyłanych danych.
1. Gdy kod jest mały i operuje na dużych ilościach danych - przesyłamy kod raz (przypisujemy statycznie dany procesor do tego jednego rodzaju zadań)
2. Gdy kod jest mały i operuje na małych ilościach danych - przesyłamy do procesora kod kilku zdefiniowanych wcześniej zadań i potem wybieramy które z tych zadań ma być wykonane
3. Gdy kod jest duży i brakuje pamięci na dane - dzielimy zadanie na części i przesyłamy kod raz do 2-3 procesorów DSP a następnie wykonujemy obliczenia na 1 procesorze, wynik przesyłamy do drugiego a potem wynik z drugiego przesyłamy do trzeciego
itd

Przy PS3 trzeba więc znać rozkład obciążenia, objętość kodu zadania i objętość danych zadania aby dobrze rozplanować przypisywanie zadań.
Tytuł: Odp: Wątki
Wiadomość wysłana przez: defeatomb w Maj 15, 2007, 22:32:03
Wracając do mojego pytania czy przyjmując synchronizację danych w aplikacjach wielowątkowych za jedeną z podstawowych rzeczy jaką trzeba uwzględnić to czy dobrym rozwiązaniem jest osobny wątek zajmujący się obsługą danych, który wykonywał by polecenia z kolejki. AddCommandToQuery i te sprawy. Pomotane ^^
Tytuł: Odp: Wątki
Wiadomość wysłana przez: nameczanin w Maj 15, 2007, 22:34:20
ja bym wpadl nawet na kolejki [jeden watek glowny] kolejek [podwatkow]. IMO why not
Tytuł: Odp: Wątki
Wiadomość wysłana przez: defeatomb w Maj 16, 2007, 10:07:00
[query]bym wpadl nawet na kolejki [jeden watek glowny] kolejek [podwatkow]. IMO why not[/query]

Dobre. Porozkminiam sobie czy mi się to przyda i ew. zakoduje ;D
Tytuł: Odp: Wątki
Wiadomość wysłana przez: pawelad w Czerwiec 20, 2007, 02:30:13
Z tego co gdzies czytalem osobny watek na rendering a osobny na AI, czy cus. Ale nikt pewnie tego nie stosuje tak jak wielordzeniwosci, sam jestem ciekaw jak by to wyszlo w praktyce, rdzenie ponoc daja kopa.