Discussion:
zapytanie o thready
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
fir
2021-01-06 11:54:33 UTC
Permalink
sam unikam pisania wielowatkowego (dosyc skutecznie na tyle ze nei mam z tym doswiadczen poza podstawowymi probami) stąd pytanie

powiedzmyz e mam pytanie ktora generuje dosc intensywnie liczac ramke obrazu (co zajmuje jej 30 milisekund), chcialbym to zrownoleglic na 2 albo cztery rdzenie

czy jest normalnym podejsciem w kazdej ramce utworzyc watek wywolacna nim funkcje liczaca pol lub jednoczwarta ekranu zrobic join na koncu do glownego threada i zamknac te watki czy tez jest to niepoprawne

pytanie dotyczy roznych api do tych watkow bo sa chyab podobne (ja bym to robil na winapi ale mozna tez rozwazyc watki z c++)

kwestia jest taka ze chyab nie da sie stworzyc tych watkow przed cala petla gry i je poprostu ponawiac/wywolywac na tych samych funkacjach co start (chyab nei ma tego w api, acz nie wczytywalem sie az tak bardzo by miec pewnosc) z api chyba by wynikalo ze nalezy je startowac joinowac i niszczyc (zamykac)

ew inna opcją do rozwazenie jest odpalenie tych pobocznych watkow tak ze kazdy ma swoją petle z systemowym sleepem osobno i po flagach (czyli po wartosciach zmiennych ) sprawdzaja czy jest cos do roboty i wtedy to robią oznaczaja ze to zrobily i przechodzą w sleep sprawdzajac co kilka milisekund czy jest nowa robota do zrobienia

odpalilem na winapowskich watkach i to pierwsze i to drugie - oba wydaja sie dzialac ale nie wiem na ile jest to poprawne i ktore lepsze...ktos tu wie cos na ten temat? googlowanie przynosi stos krapowatych watkow na pobliskie tematy bez odpowiedzi na to zasadnicze dosyc pytanie

fir
heby
2021-01-06 13:31:57 UTC
Permalink
Post by fir
czy jest normalnym podejsciem w kazdej ramce utworzyc watek
Nie. Wątki tworzy się na początku i zatrzymuje na synchronizacji,
czekając na zadania.

Tworzenie wątków jest droższe niż czekanie na semaforze.

Wiele biblitek ma do tego gotowca, thread pool.
Post by fir
kwestia jest taka ze chyab nie da sie stworzyc tych watkow przed cala petla gry i je poprostu ponawiac/wywolywac
Nie ma problemu z komunikacją międzywątkową. Zacznij od tego do czego
służa semafory.
Post by fir
ew inna opcją do rozwazenie jest odpalenie tych pobocznych watkow tak ze kazdy ma swoją petle z systemowym sleepem osobno i po flagach
Nie po flagach, tylko po prymitywach do synchronizacji. Condition,
Semafor, Kolejka.

Lub wyższych koncpecji jak future/promise i thread pool.
fir
2021-01-06 13:40:32 UTC
Permalink
Post by heby
Post by fir
czy jest normalnym podejsciem w kazdej ramce utworzyc watek
Nie. Wątki tworzy się na początku i zatrzymuje na synchronizacji,
czekając na zadania.
Tworzenie wątków jest droższe niż czekanie na semaforze.
Wiele biblitek ma do tego gotowca, thread pool.
Post by fir
kwestia jest taka ze chyab nie da sie stworzyc tych watkow przed cala petla gry i je poprostu ponawiac/wywolywac
Nie ma problemu z komunikacją międzywątkową. Zacznij od tego do czego
służa semafory.
Post by fir
ew inna opcją do rozwazenie jest odpalenie tych pobocznych watkow tak ze kazdy ma swoją petle z systemowym sleepem osobno i po flagach
Nie po flagach, tylko po prymitywach do synchronizacji. Condition,
Semafor, Kolejka.
Lub wyższych koncpecji jak future/promise i thread pool.
po flagach tez chyba powino dzialac...tyle ze byc moze w kombinacji ze sleepem
ma to jakies minusy...sleep w windzie dziala ok z pobocznymi wątkami?
heby
2021-01-06 13:46:51 UTC
Permalink
Post by fir
Post by heby
Lub wyższych koncpecji jak future/promise i thread pool.
po flagach tez chyba powino dzialac...
Nie, ponieważ albo będzie się kręcił bez sleepa, przepalając energię,
albo semafor będzie szybszy od sleepa.

W grę, z flagami, wchodzą też detale działania cache. Zmiana zmiennej w
CPU1 nie powoduje natychmiastowej widzialnosci w CPU2. W niektóych
architekturach nawet kolejnośc zmian pamięci jest nieokreślona jeśli
obserwujemy ją z innego rdzenia.
Post by fir
ma to jakies minusy...sleep w windzie dziala ok z pobocznymi wątkami?
Sleep to najgosze co można wybrać. Nie ma żadnej zalety, a same wady.
fir
2021-01-06 14:29:59 UTC
Permalink
Post by heby
Post by fir
Post by heby
Lub wyższych koncpecji jak future/promise i thread pool.
po flagach tez chyba powino dzialac...
Nie, ponieważ albo będzie się kręcił bez sleepa, przepalając energię,
albo semafor będzie szybszy od sleepa.
W grę, z flagami, wchodzą też detale działania cache. Zmiana zmiennej w
CPU1 nie powoduje natychmiastowej widzialnosci w CPU2. W niektóych
architekturach nawet kolejnośc zmian pamięci jest nieokreślona jeśli
obserwujemy ją z innego rdzenia.
Post by fir
ma to jakies minusy...sleep w windzie dziala ok z pobocznymi wątkami?
Sleep to najgosze co można wybrać. Nie ma żadnej zalety, a same wady.
nie przecze ale chodzi tez o to by to zrozumiec

co do przepalania rdzenia przez sleepa
to nei ejstem zbyt przekonany co do tego czy
jest to mozliwe bo od lat uzywam sleepa na glownym
watku obserwujac czasy ramek i tez zuzycie procka
w trayu i nigdy nie bylo tak by sleep nie zadzialal
na glowym watku.. to by nie zdzialal na pobocznym tez
wydaje mi sie wiec chyab raczej 'unexpected'

moglbym to pomierzyc timerami i poobserwowac
w zasadzie ale na razi enie che mi sie w to
wchodzic

nei wiem jak technicznie ale logicznie sleep
jest zupelnie poprawna funkcją itd

faktem jest tez jednak ze kiedys za dawnych czasow
na jakichs kompach obserwowalem ze sleep jakby byl
czasem nie wiadomo w zaleznosci od czego
wyrownywany do 15 ms nawet jak wolane bylo 5 ms
ale od lat tego nei widzialem mozliwe ze to bylo
tylko na jednordzemiakach

co do tego synchronizowania flafami tez nie jestem
pewien czy to jest zle, jak mowie zrobilem to i
raczej dzialalo choc nie robilem dokladnych
testow timerami itd - kwestia jest taka ze w tym
akurat kodzie o ktorym mowie mozna bylo zrobic na
lajcie tak by kazdy watek pisal do swojej flagi
a glowny tylko je czytal wiec nie bylo tak ze
jakies dwa pisaly do wspolnej flagi, nawet
jakby cos tam sie w czasie rozminelo o pare
mikrosekund miedzy watkami to tez nie robiloby
to problemu co najwyzej jeden poczekalby tego
jednego sleepa wiecej

ale pewnie bedzie trzena poczytac wiecej
faktycznie o tych wspomnianych rzeczach
(na poczatek uzywalbym raczej tych prostszych)

tenx za informacje bo byly pomocne, mam jakis obraz
co i jak
fir
2021-01-06 14:41:25 UTC
Permalink
Post by fir
Post by heby
Post by fir
Post by heby
Lub wyższych koncpecji jak future/promise i thread pool.
po flagach tez chyba powino dzialac...
Nie, ponieważ albo będzie się kręcił bez sleepa, przepalając energię,
albo semafor będzie szybszy od sleepa.
W grę, z flagami, wchodzą też detale działania cache. Zmiana zmiennej w
CPU1 nie powoduje natychmiastowej widzialnosci w CPU2. W niektóych
architekturach nawet kolejnośc zmian pamięci jest nieokreślona jeśli
obserwujemy ją z innego rdzenia.
Post by fir
ma to jakies minusy...sleep w windzie dziala ok z pobocznymi wątkami?
Sleep to najgosze co można wybrać. Nie ma żadnej zalety, a same wady.
nie przecze ale chodzi tez o to by to zrozumiec
co do przepalania rdzenia przez sleepa
to nei ejstem zbyt przekonany co do tego czy
jest to mozliwe bo od lat uzywam sleepa na glownym
watku obserwujac czasy ramek i tez zuzycie procka
w trayu i nigdy nie bylo tak by sleep nie zadzialal
na glowym watku.. to by nie zdzialal na pobocznym tez
wydaje mi sie wiec chyab raczej 'unexpected'
moglbym to pomierzyc timerami i poobserwowac
w zasadzie ale na razi enie che mi sie w to
wchodzic
nei wiem jak technicznie ale logicznie sleep
jest zupelnie poprawna funkcją itd
faktem jest tez jednak ze kiedys za dawnych czasow
na jakichs kompach obserwowalem ze sleep jakby byl
czasem nie wiadomo w zaleznosci od czego
wyrownywany do 15 ms nawet jak wolane bylo 5 ms
ale od lat tego nei widzialem mozliwe ze to bylo
tylko na jednordzemiakach
co do tego synchronizowania flafami tez nie jestem
pewien czy to jest zle, jak mowie zrobilem to i
raczej dzialalo choc nie robilem dokladnych
testow timerami itd - kwestia jest taka ze w tym
akurat kodzie o ktorym mowie mozna bylo zrobic na
lajcie tak by kazdy watek pisal do swojej flagi
a glowny tylko je czytal wiec nie bylo tak ze
jakies dwa pisaly do wspolnej flagi, nawet
jakby cos tam sie w czasie rozminelo o pare
mikrosekund miedzy watkami to tez nie robiloby
to problemu co najwyzej jeden poczekalby tego
jednego sleepa wiecej
logicznie to raczej trzymalo sie kupy (to czyli synchrronizacja na sleepach i flagach) wiec i technicznie
mogloby sie trzymac o ile te sleepy albo watki nie wykazywaly jakichs wewnetrznych nie znanych mi cech powodujacych ze cos tu jest nie tak

co troche nawiazuje do starego watku na CLC gdzie pisalem jak pamietam uzytkownikowi AL ze mozna synchronizowac watki nawet bez atomikow (na podobnej zasadzie o ile pamietam tylko nawet w drobniejszej skali czasowej, obecnie troche nie pamietam tamtego przykladu)

jesliby sie okazalao ze ta watki czy sleepy maja jakies cechy ktore powoduja ze sie nie sprawdzaja w tego typu kodzie to troche kiepsko bo fajnie by bylo jakby ludzie projektowali rzeczy na taki nazwijmy to "woluntarystyczny" sposob ;c
Post by fir
ale pewnie bedzie trzena poczytac wiecej
faktycznie o tych wspomnianych rzeczach
(na poczatek uzywalbym raczej tych prostszych)
tenx za informacje bo byly pomocne, mam jakis obraz
co i jak
heby
2021-01-06 15:06:49 UTC
Permalink
Post by fir
ze mozna synchronizowac watki nawet bez atomikow
W ogómym przypadku to nie jest skuteczne. W przypadku architektury x86
może być czasem możliwe.

W bardzo ogólnym wypadku wymagany jest choć fence, który trzeba jawnie
uzyć w kodzie programu. Taki mechanizm w CPU który zapewnia
synchronizację dostępu do pamięci między różnymi rdzeniami i cache.

Tak więc ogólnie rzecz biorąc nie da się zrobić sensownej synchronizacji
tylko na spilockach bo to zależy na czym to ma pracować. Zwyczajowo w
świecie wielordzeniowym trzeba się badziej postarać niż while(!flag) { }.
fir
2021-01-06 15:29:42 UTC
Permalink
Post by heby
Post by fir
ze mozna synchronizowac watki nawet bez atomikow
W ogómym przypadku to nie jest skuteczne. W przypadku architektury x86
może być czasem możliwe.
W bardzo ogólnym wypadku wymagany jest choć fence, który trzeba jawnie
uzyć w kodzie programu. Taki mechanizm w CPU który zapewnia
synchronizację dostępu do pamięci między różnymi rdzeniami i cache.
Tak więc ogólnie rzecz biorąc nie da się zrobić sensownej synchronizacji
tylko na spilockach bo to zależy na czym to ma pracować. Zwyczajowo w
świecie wielordzeniowym trzeba się badziej postarać niż while(!flag) { }.
while z pust apetla bym nei uzyl ale ze sleepem 2-3 milisekundy nie wydaje mi sie juz tak glupie..ogolne programowanie tez mnie nie kreci bo ogolne programowanie to zle porogramowanie bo w ogolnosci nie dziala optymalnie na specyficznych maszynach ;c

schemat btw raczej jaki wymodzilem byl raczej taki

int ready = 0;
do
{
while(current<ready) { sleep(2); }
do_work();
ready++;
} whie(1);

cos w tym stylu, robota dzielona na porcje numerowane liczba naturalna, current zaczyna sie od -1,
boczne watki czekaja na sleepach; glowny thread robi current++ do 0 wati ruszaja az ustawia ready na 1
glowny watek sprawdza czy wszystkie maja ready wieksze niz current jesli tak popycha current itd

w moim przekonaniu to raczej chyba powinno dzialac
fir
2021-01-06 15:38:14 UTC
Permalink
Post by fir
Post by heby
Post by fir
ze mozna synchronizowac watki nawet bez atomikow
W ogómym przypadku to nie jest skuteczne. W przypadku architektury x86
może być czasem możliwe.
W bardzo ogólnym wypadku wymagany jest choć fence, który trzeba jawnie
uzyć w kodzie programu. Taki mechanizm w CPU który zapewnia
synchronizację dostępu do pamięci między różnymi rdzeniami i cache.
Tak więc ogólnie rzecz biorąc nie da się zrobić sensownej synchronizacji
tylko na spilockach bo to zależy na czym to ma pracować. Zwyczajowo w
świecie wielordzeniowym trzeba się badziej postarać niż while(!flag) { }.
while z pust apetla bym nei uzyl ale ze sleepem 2-3 milisekundy nie wydaje mi sie juz tak glupie..ogolne programowanie tez mnie nie kreci bo ogolne programowanie to zle porogramowanie bo w ogolnosci nie dziala optymalnie na specyficznych maszynach ;c
schemat btw raczej jaki wymodzilem byl raczej taki
int ready = 0;
do
{
while(current<ready) { sleep(2); }
do_work();
ready++;
} whie(1);
cos w tym stylu, robota dzielona na porcje numerowane liczba naturalna, current zaczyna sie od -1,
boczne watki czekaja na sleepach; glowny thread robi current++ do 0 wati ruszaja az ustawia ready na 1
glowny watek sprawdza czy wszystkie maja ready wieksze niz current jesli tak popycha current itd
w moim przekonaniu to raczej chyba powinno dzialac
przez powinno mam na mysli ze odpalilem to i dzialalo (ale nie ejestem pewien czy nei przegapilem jakichs wzglednych subtelnosci), current to oczywoscie odpowiada numerowi ramki obrazu w symulacji ktora dzialac ma na okolo 50-120 fps na jednym watku zajmowala ok 30 ms na ramke wiec w optymalnym podziale roboty powinno wyjsc po 15 ms na rdzen na dwurdzeniaku... nie mierzylem czasu tylko patrzylem na oko czy jest szybciej i wylogowalem tez stany tych ready i current do loga textowego i na oko wygladalo ok

aczkolwiek zawsze jak ktos wie co tu sie moze realnie chcrzaic to wiedza o detalach mile widziana

(fir)
M.M.
2021-02-07 11:53:05 UTC
Permalink
Post by fir
Post by heby
Post by fir
ze mozna synchronizowac watki nawet bez atomikow
W ogómym przypadku to nie jest skuteczne. W przypadku architektury x86
może być czasem możliwe.
W bardzo ogólnym wypadku wymagany jest choć fence, który trzeba jawnie
uzyć w kodzie programu. Taki mechanizm w CPU który zapewnia
synchronizację dostępu do pamięci między różnymi rdzeniami i cache.
Tak więc ogólnie rzecz biorąc nie da się zrobić sensownej synchronizacji
tylko na spilockach bo to zależy na czym to ma pracować. Zwyczajowo w
świecie wielordzeniowym trzeba się badziej postarać niż while(!flag) { }.
while z pust apetla bym nei uzyl ale ze sleepem 2-3 milisekundy nie wydaje mi sie juz tak glupie..ogolne programowanie tez mnie nie kreci bo ogolne programowanie to zle porogramowanie bo w ogolnosci nie dziala optymalnie na specyficznych maszynach ;c
schemat btw raczej jaki wymodzilem byl raczej taki
int ready = 0;
do
{
while(current<ready) { sleep(2); }
do_work();
ready++;
} whie(1);
cos w tym stylu, robota dzielona na porcje numerowane liczba naturalna, current zaczyna sie od -1,
boczne watki czekaja na sleepach; glowny thread robi current++ do 0 wati ruszaja az ustawia ready na 1
glowny watek sprawdza czy wszystkie maja ready wieksze niz current jesli tak popycha current itd
w moim przekonaniu to raczej chyba powinno dzialac
przez powinno mam na mysli ze odpalilem to i dzialalo (ale nie ejestem pewien czy nei przegapilem jakichs wzglednych subtelnosci), current to oczywoscie odpowiada numerowi ramki obrazu w symulacji ktora dzialac ma na okolo 50-120 fps na jednym watku zajmowala ok 30 ms na ramke wiec w optymalnym podziale roboty powinno wyjsc po 15 ms na rdzen na dwurdzeniaku... nie mierzylem czasu tylko patrzylem na oko czy jest szybciej i wylogowalem tez stany tych ready i current do loga textowego i na oko wygladalo ok
aczkolwiek zawsze jak ktos wie co tu sie moze realnie chcrzaic to wiedza o detalach mile widziana
(fir)
A jakby użyć OpenCL?

Pozdrawiam

heby
2021-01-06 15:03:02 UTC
Permalink
Post by fir
co do przepalania rdzenia przez sleepa
Sleep nic nie przepala. Busy wait przepala (spin lock) czekający w pętli
na zmienną. Istnieją hybryty spinlock z condition które zapewniają
troche wiecej zjadanej energii i szybką reakcję.

W dodatku poprawne napisanie szybkiego spinlocka jest bardzo trudne (z
uwagi na synchronizacje cache na różnych architekturach cpu). Zazwyczaj
takie mechanizmy są dostarczane w formie biblitek, aby program nie
zajmował się detalami działania peocesora.
Post by fir
nei wiem jak technicznie ale logicznie sleep
Bo mylisz sleep z busy wait.

Sleep jest najgorszy, bo gwarantuje najgorszą responsywaność i ma taki
sam profil energetyczny jak semafor.

Busy wait jest najszybszy, ale tylko pod warunkiem że potrafisz go
poprawnie napisać (cache) i masz prąd za darmo.

Semafor jest najlepszy "w gólnym przypadku". Jesli masz przypadek
krytycznie ważny pod kątem wydajności, to hybryda spinlock z
condition/semafor.
fir
2021-01-06 13:46:26 UTC
Permalink
Post by heby
Post by fir
czy jest normalnym podejsciem w kazdej ramce utworzyc watek
Nie. Wątki tworzy się na początku i zatrzymuje na synchronizacji,
czekając na zadania.
Tworzenie wątków jest droższe niż czekanie na semaforze.
Wiele biblitek ma do tego gotowca, thread pool.
Post by fir
kwestia jest taka ze chyab nie da sie stworzyc tych watkow przed cala petla gry i je poprostu ponawiac/wywolywac
Nie ma problemu z komunikacją międzywątkową. Zacznij od tego do czego
służa semafory.
Post by fir
ew inna opcją do rozwazenie jest odpalenie tych pobocznych watkow tak ze kazdy ma swoją petle z systemowym sleepem osobno i po flagach
Nie po flagach, tylko po prymitywach do synchronizacji. Condition,
Semafor, Kolejka.
Lub wyższych koncpecji jak future/promise i thread pool.
a jest wogole jakis w miare krotki ale dobry tutorial do tego ? najlpeiej cos co opisywaloby zadanie zblizone do tego co opisalem na poczatku (czyli kod liczacy co ramke ekran ktory chcialbym podzielic tak by odzielne watki liczyly odzielne kawalki)

gdy goglowalem za tym parenascie di temu nic sensownego sie w google nie pojawialo.w same te watki za gleboko nie che wchodzic bo jak na dzis nie przepadam za tym 'tematem'
Loading...