Forum » Programiranje » (Java) Threading in Multithreading CPU
(Java) Threading in Multithreading CPU
marjan_h ::
Torej ne gre samo za Javo, ampak na splošno za vse jezike. Našel sem tole za primer: https://www.tutorialspoint.com/java/jav...
Današnji CPU-ji imajo ponavadi 2 niti na jedro. Kjer so od 2 do 32 jedrni. Če imamo samo 1-jedrni procesor in ima 2 niti. To pomeni, da lahko spawnamo največ 2 programski niti, v tem example programu kot je primer v zgornjem primeru na tem CPU-ju? Seveda da bo delovalo...
Hvala za obrazložitev.
Današnji CPU-ji imajo ponavadi 2 niti na jedro. Kjer so od 2 do 32 jedrni. Če imamo samo 1-jedrni procesor in ima 2 niti. To pomeni, da lahko spawnamo največ 2 programski niti, v tem example programu kot je primer v zgornjem primeru na tem CPU-ju? Seveda da bo delovalo...
Hvala za obrazložitev.
Gejspodar ::
marjan_h ::
Zdravo,
Niti jedra in current niti v operacijskem sistemu se malce razlikujejo. Ti lahko programsko ustvariš nebroj (elipsa) niti, pa jih bo procesor še vedno shandlal. Lahko npr. pogledaš (če imaš Windows) v Task Managerju število threadov, pa jih boš imel 1000x več, "kot jih ima tvoj procesor".
Tega nisem vedel. Vendar, zakaj potem delimo stvari na hardware niti in software niti? Niti ne vem, zakaj se podprogram/podproces imenuje nit in kaj je to potem pri hardwareu. :/
kow ::
Proces se ne izvaja, ampak nit -> to je "execution unit". Istega threada ne mores istocasno izvajati v 2 razlicnih jedrih. Proces pa je sestavljen iz vecih niti, in vsi se lahko hkrati izvajajo paralelno (ce niso povezani, kar sicer ponavadi ne drzi).
Ce bos imel OS s 50 procesi (torej vsaj 50 niti, ampak v praksi vec, ker ima proces ponavadi vec niti), na procesorju, ki ima 1 jedro, bo to hkrati lahko izvajalo samo 1 nit.
Ce bos imel OS s 50 procesi (torej vsaj 50 niti, ampak v praksi vec, ker ima proces ponavadi vec niti), na procesorju, ki ima 1 jedro, bo to hkrati lahko izvajalo samo 1 nit.
Zgodovina sprememb…
- spremenil: kow ()
marjan_h ::
Proces se ne izvaja, ampak nit -> to je "execution unit". Istega threada ne mores istocasno izvajati v 2 razlicnih jedrih. Proces pa je sestavljen iz vecih niti, in vsi se lahko hkrati izvajajo paralelno (ce niso povezani, kar sicer ponavadi ne drzi).
To pomeni, če bi napisal program z večimi funkcijami in tudi, če te funkcije niso napisane asinhrono ampak sinhrono bi se izvajale paralelno? Npr. z async keywordom v Pythonu ali Javascripti.
Ce bos imel OS s 50 procesi (torej vsaj 50 niti, ampak v praksi vec, ker ima proces ponavadi vec niti), na procesorju, ki ima 1 jedro, bo to hkrati lahko izvajalo samo 1 nit.
To je v nasprotju, kar je Gejspodar napisal. Torej enojedrni procesor z eno hardwaresko nitjo izvaja lahko hkrati največ eno programsko nit. Če ima ta enojedrni procesor 2 hardwareski niti, potem lahko izvaja hkrati največ 2 niti?
Spura ::
Ne govorimo hardwareski niti.
Kar se OSa tice sta to 2 procesorja. Kar se hardwarea tice to nista dva polna procesorja ampak en z dvema execution pipelineoma, in Intelov marketinski izraz za to je hyperthreading. V osnovi OS daje delo dvema logicnema procersorjema in potem se hardware ukvarja kaj to pomeni zanj.
Kar se pa tice Threadov v OSu, teh je lahko kolikor hoces (no, omejeno z RAMom), od OSa scheduler jih daje izmenicno v izvajanje procesorjem. Tako jih lahko en procesor izjava mnogo (ampak ne hkrati). Potem imas pa se Green Threade.
Kar se OSa tice sta to 2 procesorja. Kar se hardwarea tice to nista dva polna procesorja ampak en z dvema execution pipelineoma, in Intelov marketinski izraz za to je hyperthreading. V osnovi OS daje delo dvema logicnema procersorjema in potem se hardware ukvarja kaj to pomeni zanj.
Kar se pa tice Threadov v OSu, teh je lahko kolikor hoces (no, omejeno z RAMom), od OSa scheduler jih daje izmenicno v izvajanje procesorjem. Tako jih lahko en procesor izjava mnogo (ampak ne hkrati). Potem imas pa se Green Threade.
kow ::
Obstajajo hw optimizacije, ki malo zakomplicirajo zadeve, ker - kot je napisal spura - rac. jedro potem ni vec enostavni "sekvencni stroj".
Ampak z osnovnega stalisca razumevanja threada, ce predpostavimo, da procesor ne podpira multithreadinga: kolikor jeder, toliko hkratnih threadov.
Iz wikipedie:
" a thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler,"
V principu so programi nizi instrukcij, razsekani in poganjani v kosih (del kernela, torej tudi program, ki se imenuje scheduler)
Ampak z osnovnega stalisca razumevanja threada, ce predpostavimo, da procesor ne podpira multithreadinga: kolikor jeder, toliko hkratnih threadov.
Iz wikipedie:
" a thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler,"
V principu so programi nizi instrukcij, razsekani in poganjani v kosih (del kernela, torej tudi program, ki se imenuje scheduler)
Zgodovina sprememb…
- spremenil: kow ()
Wrop ::
To pomeni, če bi napisal program z večimi funkcijami in tudi, če te funkcije niso napisane asinhrono ampak sinhrono bi se izvajale paralelno? Npr. z async keywordom v Pythonu ali Javascripti.
CPU ti lahko iz različnih razlogov ustavi izvajanje tvojega programa in na katerokoli točki tvojega programa. Ponavadi v tej točki nadzor nad CPU prevzame OS in ta določi kaj se bo izvajalo naprej. Tvoja funkcija je lahko sinhrona ali asinhrona, to nima nobenega vpliva.
Funkcije v programu se same po sebi ne bodo kar odločile izvajati se paralelno. Nekdo jih mora klicati. Recimo, da si ustvaril dve niti in obe niti kličeta isto funkcijo v isti instanci. Zadeva se lahko razplete na mnogo načinov. Skozi funckijo se lahko najprej prebije
ena nit, lahko se druga, lahko pa ravno med izvajanjem ene niti, nadzor nad CPU prevzame OC in delo dodeli drugi niti. S stališča programerja se je zadeva izvedla paralelno, pa naj si bo na enojedrnem CPU ali pa večjedrnem.
Ce bos imel OS s 50 procesi (torej vsaj 50 niti, ampak v praksi vec, ker ima proces ponavadi vec niti), na procesorju, ki ima 1 jedro, bo to hkrati lahko izvajalo samo 1 nit.
To je v nasprotju, kar je Gejspodar napisal. Torej enojedrni procesor z eno hardwaresko nitjo izvaja lahko hkrati največ eno programsko nit. Če ima ta enojedrni procesor 2 hardwareski niti, potem lahko izvaja hkrati največ 2 niti?
Iz stališča CPU se v enojedrnem CPU v nekem časovnem intervalu izvaja naenkrat izvaja ena nit. No strogo tehnično gledano niti to ni povsem res. Namreč CPU niso samo regitri in predpomnilnik. Imaš DMA krmilnike, ki lahko za en drug program izvaja kopiranje podatkov iz enega dela pomnilnika v drug del ali pa iz/v zunanji del CPU. Lahko se zgodi, da je nek časovnik v CPU ravno v isti urini periodi poslal prekinitveni signal, in CPU bo morda poskrbel, da bo naslednjo urino periodo že pripravljal, da bo naložil naslov za izvedbo prekinitvenega programa za ta časovnik. V CPU se dogaja marsikaj, kar kot programer ene aplikacije niti ne rabiš vedet niti nočeš vedet, ker je tega ogromno.
S stališča programerja na višjem nivoju (bolj pri uporabniku), pa v večini primerov niti ne rabiš vedet kako so jedra v CPU implementirana in kako se zadeve izvajajo. Sploh pa ne pri Javi/Javascriptu.
Zimonem ::
To pomeni, če bi napisal program z večimi funkcijami in tudi, če te funkcije niso napisane asinhrono ampak sinhrono bi se izvajale paralelno? Npr. z async keywordom v Pythonu ali Javascripti.
V osnovi ne. Imata pa oba jezika nekaj backendov , ki to znaj storit.
Ali pa predajo knjižnicam katere poskrbijo za to. Asinshronost pomeni zgolj neusklajenost. Oz potrebno po neusklajenosti. Načeloma to ni nič drugega kot korutine enkjer je koda reanranžira v nekaj kar se preverja v loopu ali nima izpolnjene pogoje za nadaljnje izvajanje, ker sama funkcija ne pomeni nič sama po sebi se zahteva še asinhron io. Ja in py sta če osnovi enonitna. Imaš pa potem vmje ki se grejo n:m mapiranje na niti operacijski sistem često preko thread poola. Ampak potem moraš poskrbeti za vso soodvisnost med nitmi sam.
Ali pa prenesti določene na drug sistem ti se često zgodi dandanes , ko nek del asinhrone funkcije drži povezavo do podatkovne baze/storega
.
win64 ::
Izhajam prtežno iz C# okolja. In tam je async implementiran preko nekakšnega Task factory. Metodo označiš, da je asinhrona; ta metoda se potem pri klicu razporedi v prosto nit za izvajanje. Niti načeloma lahko obstajajo odprte - nepreverjeno.
Je pa pri C# ta task pool abstrakcija. To pomeni, da obstajajo različne implementacije tega poola glede na izvajalno okolje. Zato ni niti nujno, da se task izvede asinhrono. Lahko pa sam implementiraš TaskFactory po svoje.
Primera:
- Zahevki v .Net Framework AspNet Web aplikaciji tečejo v eni niti.
- V winForms aplikacijah je ta pool implementiran s pomočjo message loop.
Druga možnost je, da sam ustvarjaš niti. To bolj v primeru, ko res želiš "neodvisno" izvajanje kode. Primer: ena nit sprejema in polni seznam zahtevkov za obdelavo, druga nit(ali več njih) obdeluje zahtevke.
V vsakem primeru pa moraš misliti na to, da lahko dve niti dostopata in zapisujeta do istega podatka istočasno. Če nimaš tega v mislih, lahko pride do zares čudnih in naključnih napak.
Kot zanimivost: v .Net okolju je večina gonilnikov za baze napisanih tako, da imajo connection pool. Podobno kot TaskPool niti, connection pooli držijo določeno število povezav odprtih. Odpiranje povezav potem ni tako drago.
Je pa pri C# ta task pool abstrakcija. To pomeni, da obstajajo različne implementacije tega poola glede na izvajalno okolje. Zato ni niti nujno, da se task izvede asinhrono. Lahko pa sam implementiraš TaskFactory po svoje.
Primera:
- Zahevki v .Net Framework AspNet Web aplikaciji tečejo v eni niti.
- V winForms aplikacijah je ta pool implementiran s pomočjo message loop.
Druga možnost je, da sam ustvarjaš niti. To bolj v primeru, ko res želiš "neodvisno" izvajanje kode. Primer: ena nit sprejema in polni seznam zahtevkov za obdelavo, druga nit(ali več njih) obdeluje zahtevke.
V vsakem primeru pa moraš misliti na to, da lahko dve niti dostopata in zapisujeta do istega podatka istočasno. Če nimaš tega v mislih, lahko pride do zares čudnih in naključnih napak.
Kot zanimivost: v .Net okolju je večina gonilnikov za baze napisanih tako, da imajo connection pool. Podobno kot TaskPool niti, connection pooli držijo določeno število povezav odprtih. Odpiranje povezav potem ni tako drago.
kow ::
To pomeni, če bi napisal program z večimi funkcijami in tudi, če te funkcije niso napisane asinhrono ampak sinhrono bi se izvajale paralelno? Npr. z async keywordom v Pythonu ali Javascripti.
V osnovi ne. Imata pa oba jezika nekaj backendov , ki to znaj storit.
Ali pa predajo knjižnicam katere poskrbijo za to. Asinshronost pomeni zgolj neusklajenost. Oz potrebno po neusklajenosti. Načeloma to ni nič drugega kot korutine enkjer je koda reanranžira v nekaj kar se preverja v loopu ali nima izpolnjene pogoje za nadaljnje izvajanje, ker sama funkcija ne pomeni nič sama po sebi se zahteva še asinhron io. Ja in py sta če osnovi enonitna. Imaš pa potem vmje ki se grejo n:m mapiranje na niti operacijski sistem često preko thread poola. Ampak potem moraš poskrbeti za vso soodvisnost med nitmi sam.
Ali pa prenesti določene na drug sistem ti se često zgodi dandanes , ko nek del asinhrone funkcije drži povezavo do podatkovne baze/storega
.
Isti enostavni program lahko zazenes (skoraj) hkrati. Recimo, da ima samo eno funkcijo, ki v loopu nekaj izracunava. Torej, bos imel 2 niti (in 2 procesa), vsaka v svojem jedru. Dobil si paralelizem, ki ni sinhroniziran.
Zgodovina sprememb…
- spremenil: kow ()
Zimonem ::
Če Linuxu je rahlo bolje ker Elf je manj obremenjen kot Windowsiov PE. Ampak sinhronizacija je tu bistven problem. Ok. IPC lahko izvajaš tudi prek nogavičk. Ampak prepočasi. Konec koncev gremo lahko potem tudi na mq. Samo kje si potem pridobil pohitritev.
win64 ::
Če Linuxu je rahlo bolje ker Elf je manj obremenjen kot Windowsiov PE. Ampak sinhronizacija je tu bistven problem. Ok. IPC lahko izvajaš tudi prek nogavičk. Ampak prepočasi. Konec koncev gremo lahko potem tudi na mq. Samo kje si potem pridobil pohitritev.
Lahko podaš malo več informaciji o tem, da je Elf manj obremenjen kot PE?
pegasus ::
V CPU se dogaja marsikaj, kar kot programer ene aplikacije niti ne rabiš vedet niti nočeš vedet, ker je tega ogromno.In potem se pojavijo vprašanja, kot ga je zastavil Op.
S stališča programerja na višjem nivoju (bolj pri uporabniku), pa v večini primerov niti ne rabiš vedet kako so jedra v CPU implementirana in kako se zadeve izvajajo. Sploh pa ne pri Javi/Javascriptu.
IMHO vsak programer *mora* razumeti vsaj osnove, kaj počne cpu in kako to počne ter kakšna je arhitektura ciljanih sistemov. Toliko bolj, če se ustvarja kaj na nivoju operacijskega sistema ali pa kaj, kjer je hitrost izvajanja pomembna. Če je preveč abstrakcije, dobimo samo sranje, kakršen je povečini današnji softver.
win64 ::
Seveda v višje nivojskih jezikih ne boš pisal gonilnikov in low level zadev.
Če pa pišeš recimo neko poslovno logiko je pa že iz vidika vzdržljivosti kode dobro pisati v višje nivojskih jezikih. Potem je tukaj še prenosljivost kode.
Pisanje programov, ki se prevedejo v bytecode za VM, pa ni nujno slabo za hitrost. VM lahko med izvajanjem prevaja kodo glede na izvajalno okolje - recimo glede na zmogljivost procesorja SSE/SSE2..
To bi recimo v C++ pomenilo, da bi moral pripraviti knjižnico za vsak procesor posebej.
Nevem kaj se javascript sploh vleče v temo o večnitnosti. V brskalniku teče aplikacija v eni niti. Edina možnost, da se v javascript nekaj res zaganja pararelno je preko service workerjev, ki pa ni nujno, da ima svoj proces/nit. Težav s sočasnim dostopom pa ni, ker se aplikacija in service worker lahko pogovarjajo samo preko message. Async pa je tako ali tako samo kozmetični bombonček.
Če pa pišeš recimo neko poslovno logiko je pa že iz vidika vzdržljivosti kode dobro pisati v višje nivojskih jezikih. Potem je tukaj še prenosljivost kode.
Pisanje programov, ki se prevedejo v bytecode za VM, pa ni nujno slabo za hitrost. VM lahko med izvajanjem prevaja kodo glede na izvajalno okolje - recimo glede na zmogljivost procesorja SSE/SSE2..
To bi recimo v C++ pomenilo, da bi moral pripraviti knjižnico za vsak procesor posebej.
Nevem kaj se javascript sploh vleče v temo o večnitnosti. V brskalniku teče aplikacija v eni niti. Edina možnost, da se v javascript nekaj res zaganja pararelno je preko service workerjev, ki pa ni nujno, da ima svoj proces/nit. Težav s sočasnim dostopom pa ni, ker se aplikacija in service worker lahko pogovarjajo samo preko message. Async pa je tako ali tako samo kozmetični bombonček.
predi ::
V glavnem, za paralelno izvajanje enega ali več programov je dovolj en eno-jedrni eno-nitni procesor, ki ga sistem obravnava kot en deljen resurs. Programom (procesom, nitim) je lahko dodeljen procesor za neko časovno enoto, ko se ta izteče, pride na vrsto nekdo drug. Shrani se trenutno stanje, ki se nato ponovno naloži, ko program oz. njegov del spet pride na vrsto. Navzven je to videti, kot da se več programov ali delov istega programa izvaja hkratno, čeprav temu ni tako. Vse kar je pri več-jedrnih oz. več-nitnih procesorjih drugače, je to, da je število deljenih resursov večje (torej jih je na razpolago več), upravljanje z njimi pa bolj kompleksno - v zameno za še več paralelizma. Kako je procesor dejansko dodeljen programom oziroma ukazom v njih, je lahko doseženo na več različnih načinov, sam sem opisal samo enega (časovno omejeno deljenje). Bistvo več-nitnega izvajanja enega programa je lahko ravno v boljšem izkoristku enega procesorskega jedra, ne nujno več njih.
kow ::
V glavnem, za paralelno izvajanje enega ali več programov je dovolj en eno-jedrni eno-nitni procesor, ki ga sistem obravnava kot en deljen resurs.
To ni paralelizem, ampak concurrency. Da se vec programov izvaja hkrati, ne drzi. Samo uporabniku se tako dozdeva.
Zgodovina sprememb…
- spremenil: kow ()
kow ::
Ne vem kaj hoces povedati. Povedal sem ti, da si se napacno izrazil. Z razlogom obstaja 2 razlicni besedi.
Zimonem ::
V glavnem, za paralelno izvajanje enega ali več programov je dovolj en eno-jedrni eno-nitni procesor, ki ga sistem obravnava kot en deljen resurs. Programom (procesom, nitim) je lahko dodeljen procesor za neko časovno enoto, ko se ta izteče, pride na vrsto nekdo drug. Shrani se trenutno stanje, ki se nato ponovno naloži, ko program oz. njegov del spet pride na vrsto. Navzven je to videti, kot da se več programov ali delov istega programa izvaja hkratno, čeprav temu ni tako. Vse kar je pri več-jedrnih oz. več-nitnih procesorjih drugače, je to, da je število deljenih resursov večje (torej jih je na razpolago več), upravljanje z njimi pa bolj kompleksno - v zameno za še več paralelizma. Kako je procesor dejansko dodeljen programom oziroma ukazom v njih, je lahko doseženo na več različnih načinov, sam sem opisal samo enega (časovno omejeno deljenje). Bistvo več-nitnega izvajanja enega programa je lahko ravno v boljšem izkoristku enega procesorskega jedra, ne nujno več njih.
Trapaš kot avaša. Nimaš pa pojma o pojmu.
Do iste alocirane memorije ti lahko vzporedni procesi dostopajo istočasno. Kaj se pa logično dogaja pri asinhronih funkcijah ki se izvajajo zaporedno pa ti nima veze.
Zgodovina sprememb…
- spremenilo: Zimonem ()
predi ::
Izvolijo definicijo več-nitnosti (multithreading): klik, kot jo poznam sam in kot so nam jo posredovali na različnih instancah našega izobraževalnega sistema.
Javanski Thread, ki je bil povod za OP-ovo vprašanje, je bil na voljo pred več-jedrnimi procesorji, ki so dandanes nekaj običajnega. Od kje informacija, da si niti ne morejo deliti dodeljenega spomina, pa ne vem.
In computer architecture, multithreading is the ability of a central processing unit (CPU) (or a single core in a multi-core processor) to provide multiple threads of execution concurrently, supported by the operating system. This approach differs from multiprocessing. In a multithreaded application, the threads share the resources of a single or multiple cores, which include the computing units, the CPU caches, and the translation lookaside buffer (TLB).
Where multiprocessing systems include multiple complete processing units in one or more cores, multithreading aims to increase utilization of a single core by using thread-level parallelism, as well as instruction-level parallelism. As the two techniques are complementary, they are combined in nearly all modern systems architectures with multiple multithreading CPUs and with CPUs with multiple multithreading cores.
Javanski Thread, ki je bil povod za OP-ovo vprašanje, je bil na voljo pred več-jedrnimi procesorji, ki so dandanes nekaj običajnega. Od kje informacija, da si niti ne morejo deliti dodeljenega spomina, pa ne vem.
kow ::
Zdaj smo se zaceli zapletati v detajle in se "prepucavati". Predi je napisal, da imajo moderna jedra fine-grained nitnost. Ampak, imo je sedaj na OPju, da pojasni, ce je sedaj dobil vsaj intuitivno razumevanje kaj je nit s stalisca operacijskega sistema.
Ce bo razlikoval med besedami kot so thread, process, concurrency, parallelism, kernel, scheduler, context (switch) itd., bo naceloma sam lahko interpretiral razlage na netu.
Ce bo razlikoval med besedami kot so thread, process, concurrency, parallelism, kernel, scheduler, context (switch) itd., bo naceloma sam lahko interpretiral razlage na netu.
Wrop ::
V CPU se dogaja marsikaj, kar kot programer ene aplikacije niti ne rabiš vedet niti nočeš vedet, ker je tega ogromno.In potem se pojavijo vprašanja, kot ga je zastavil Op.
S stališča programerja na višjem nivoju (bolj pri uporabniku), pa v večini primerov niti ne rabiš vedet kako so jedra v CPU implementirana in kako se zadeve izvajajo. Sploh pa ne pri Javi/Javascriptu.
IMHO vsak programer *mora* razumeti vsaj osnove, kaj počne cpu in kako to počne ter kakšna je arhitektura ciljanih sistemov. Toliko bolj, če se ustvarja kaj na nivoju operacijskega sistema ali pa kaj, kjer je hitrost izvajanja pomembna. Če je preveč abstrakcije, dobimo samo sranje, kakršen je povečini današnji softver.
Kaj točno počne CPU in kakšna je točna arhitektura ciljanih sistemov ve zelo malo programerjev. Sploh pa java/javascript programerjev. Verjetno bo to amd86_64 ali arm64. Sploh pa pri out of order execution procesorjih programer ne more točno vedeti kaj točno se dogaja v cpu. V resnici ni niti pomembno. Za veliko večino. Važno je samo, da ima programer zagotovljeno sekvenčno izvajanje napisane kode. Pa naj to zagotovi prevajalnik bodisi cpu ali oba.
Se pa strinjam, da programerji na OS nivoju morajo to bistveno bolje v detalje poznati, saj je od njih odvisno, kakšno transparentnost bo zagotovljena programerjem na višjem nivoju. Prav nobene potrebe ni, da bi se morali programerji na aplikacijskem nivoju ukvarjati, kako bodo poslali nek paket preko TCP/IP protokola, da bo neka baza nekje nekaj obdelala in poslala odgovor nazaj.
Abstakcija sama po sebi ni slaba, tudi, če jo je preveč. Problem je velikokrat, da se gre na novejše in neprizkušene zadeve, pri tem pa velikokrat trpi zanesljivost in hitrost. Dobimo sranje.
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Python primer async/awaitOddelek: Programiranje | 2133 (1239) | jype |
» | [JS] AsinhronostOddelek: Programiranje | 1888 (1356) | GupeM |
» | AsinhronostOddelek: Programiranje | 2572 (2341) | mihies |
» | niti (threads) (strani: 1 2 )Oddelek: Programiranje | 5171 (3625) | noraguta |
» | Desktop aplikacije večinoma niso multithreaded??? (strani: 1 2 )Oddelek: Programiranje | 4885 (4131) | Gundolf |