Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Podešavanje zaokrugljivanja i višenitnost

[es] :: Art of Programming :: Podešavanje zaokrugljivanja i višenitnost

[ Pregleda: 2393 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
89.216.32.*



+2789 Profil

icon Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 10:29 - pre 156 meseci
Standardni C/C++ imaju zaglavlje fenv.h sa funkcijama koje omogućavaju podešavanje zaokrugljivanja pri operacijama u pokretnom zarezu. Postoje četiri načina zaokrugljivanja:

1. FE_TONEAREST - Na najbližu vrednost (podrazumevano),
2. FE_DOWNWARD - prema ,
3. FE_UPWARD - prema ,
4. FE_TOWARDZERO - prema nuli.

Ukoliko koristite VC++, zaboravite na ovo, a ako koristite GNU prevodioce, prilikom prevođenja neophodno je zadati direktivu -frounding-math.

Pozivom funkcije fesetround() sa jednom od četiri navedene konstante kao parametrom podešava način zaokruglivanja za naredne matematičke operacije u pokretnom zarezu do sledeće promene pozivom te funkcije. Koliko sam imao prilik da vidim, funkcija fesetround() nije bezbedna za niti, tj. ne deluje samo na nit u kojoj je pozvana, nego na ceo proces, ali ne i na druge procese.

Ja shvatam da se na taj način kaže procesoru kako da radi sa narednim operacijama u pokretnom zarezu, a da sam procesor ne zna šta je to nit, a šta proces. Međutim, muče me dva pitanja:

A) Da li po pitanju neremećenja drugih procesa na sistemu pozivom te funkcije mogu mirno da spavam? Kako se obezbeđuje da poziv te funkcije ne utiče na druge procese na sistemu? Ako je stvar u tome da se to stanje na neki način snimi prilikom prekida izvršavanja procesa i posle restaurira kada na njegovo izvršavanje ponovo dođe red, kako to onda može da funkcioniše ako se taj drugi proces stalno izvršava, bez prekida (na višejezgarnom procesoru)?

B) Mogu li se niti sinhronizovati po pitanju zaokrgljivanja (da svaka menja režim samo za sebe) bez korišćenja mjuteksa? Recimo, da postoji neka funkcija koja se poziva kada nit ide na spavanje, koja bi sačivala stanje i neka funkcija koja se poziva kada se nit probudi, koja bi restaurirala stanje? Ako pozivanje ove funkcije zaista ne utiče na druge procese, ne bi trebalo da postoji fundamentalan razlog da se to ne može obezbediti za niti.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3453

Jabber: djoka_l


+1462 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 10:54 - pre 156 meseci
Režim zaokrugljivanja se postavlja setovanjem FPU Control Registra na odgovarajuću vrednost.
Pogledaj: http://www.arl.wustl.edu/~lock...rtofasm/Chapter_14/CH14-3.html

Nezavisnost režima zaokruživanja između procesa se postiže time što se FPU Control Registar čuva prilikom prekida procesa (u kontekstu procesa).
Čuvanje ovog registra nije "automatsko" nego je odgovornost OS-a da sačuva ono što je bitno, tako da za čuvanje "konteksta niti" koje nije direktno podržano u delu koji se tiče FPU CR moraš sam da se pobrineš, tj. da koristiš semafore.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
89.216.32.*



+2789 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:05 - pre 156 meseci
Hvala na odgovoru, ali mislim da nisi pažljivo pročitao pitanje pod A).

Sve je to lepo na jednom jezgru, gde jedan proces mora biti prekinut da bi drugi radio, ali šta u slučaju višejezgarnih procesora? Recimo, imaš 10 procesora sa po dva jezgra. Jezgra jednog od procesora izvršavaju neka dva procesa, a ostalih 9 procesora obavljaju sve ostalo. Dakle, ta dva procesa se ne prekidaju nikada i izvršavaju se na istom procesoru. Kako onda ne utiču jedan na drugog?

Što se semafor atiče, nisam te baš razumeo. Ja sam problem rešio preko mjuteksa.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3453

Jabber: djoka_l


+1462 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:11 - pre 156 meseci
Ok, da probam da dopunim odgovor.

Nije mi poznato koliko FPU-a imaju višejezgarni procesori, ali možemo da pretpostavimo da ih ima manje nego jezgara (u slučaju da ih ima isto, rešenje je trivijalno - svako koristi svoj FPU).

Dakle, rešenje je isto kao i kod korišćenje bilo kog deljenog resursa - resurs se dodeli, koristi pa onda pusti. Pre dodele FPU-a procesu, snimi se kontekst FPU-a, pa se vrati kada ga ponovo dobije prekinut proces.

U tvom primeru, 10 procesora sa po 2 jezgra, svaki od procesora ima bar po jedan FPU. Svaki proces koristi FPU koji se nalazi na onom procesoru čije jedno jezgro izvršava proces.

A pretpostavka da se dva procesa ne prekidaju nikad nije tačna. Ako bi sistem dozvolio da neki proces može da radi neprekidno, tada ne bi bilo ništa od multitaskinga, a svako bi mogao da napiše program koji ekskluzivno koristi jezgro.
 
Odgovor na temu

deerbeer
Beograd

Član broj: 174418
Poruke: 1189
*.dynamic.sbb.rs.



+395 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:13 - pre 156 meseci
Pogledaj ovde ces mozda naci dobre alatke za rad sa multicore jezgrima.
http://software.intel.com/en-u...es/intel-parallel-studio-home/
Viva lollapalooza
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
89.216.32.*



+2789 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:30 - pre 156 meseci
Citat:
djoka_l: A pretpostavka da se dva procesa ne prekidaju nikad nije tačna. Ako bi sistem dozvolio da neki proces može da radi neprekidno, tada ne bi bilo ništa od multitaskinga, a svako bi mogao da napiše program koji ekskluzivno koristi jezgro.


Kako ništa od multitaskinga, kad imaš još 9 procesora?
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3453

Jabber: djoka_l


+1462 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:31 - pre 156 meseci
Još jedna dopuna:

Na slici: http://en.wikipedia.org/wiki/File:Intel_Core2_arch.svg se vidi da ipak svako jezgro ima svoj FPU, tako da je slučaj trivijalan (ako sam dobro protumačio sliku)....
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
89.216.32.*



+2789 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:37 - pre 156 meseci
A zašto onda nije sređeno da niti ne utiču jedna na drugu?
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3453

Jabber: djoka_l


+1462 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:46 - pre 156 meseci
http://www.cafeaulait.org/course/week11/02.html

Snimanje i vraćanje konteksta procesa je skupa operacija. Zato su i izmišljene niti, imaš paralelizam, s tim da niti dele neke resurse.

Citat:
Nedeljko: Kako ništa od multitaskinga, kad imaš još 9 procesora?

Neka imaš i 90 procesora, uvek možeš da napišeš program koji formira onoliko procesa koliko imaš jezgara, pa da ubiješ sistem. U svakom slučaju, moraš da imaš interapt koji se okida kada istekne time slice koji je dodeljen procesu, čisto da proveriš da li ima neki drugi proces koji čeka na procesor, pa ako nema, da vratiš kontekst prekinutog procesa.

To je bio problem starijih verzija windowsa, jer su interapti mogli da nastupe samo kada proces pozove servis operativnog sistema, pa je moglo lako da se desi da greškom ili namerno uzurpiraš procesor...
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3453

Jabber: djoka_l


+1462 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 11:50 - pre 156 meseci
Pravo pitanje za tebe je zašto ti je potrebno da thread ima drugačiji mehanizam zaokruživanja. Threadovi bi morali da se ponašaju na isti način. Možda tvoj koncept nije dobar, možda ti trebaju pravi procesi, u kojima bi važila drugačija pravila.

Na primer: želiš da obrađuješ sliku, pa u zavisnosti od toga koliko imaš jezgara, podeliš sliku na toliko segmenata, pa svaki thread radi sa jednim segmentom slike. U ovom slučaju je jasno da threadovi moraju da računaju na isti način sa FP brojevima.

Drugi primer: pišeš program koji radi numeričku integraciju koristeći nekoliko različitih algoritama, pa onda želiš da uporediš rezultate. U tom slučaju je jasno da svaki algoritam može da se izvršava kao poseban proces, a da threadovi nemaju smisla, osim ako ne želiš da svaki pojedini algoritam izvršavaš u više threadova. Tada threadovi jedno algoritma moraju da koriste iste postavke, dok oni koji pripadaju nekom drugom procesu ne moraju.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
89.216.32.*



+2789 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 12:27 - pre 156 meseci
Evo za šta mi trebaju - da napravim intervalnu algebru bezbednu za niti. boost-ova klasa boost::numeric::Interval nije bezbedna za niti, ne vrši sva računanja korektno (acos(-1) zbog baga u intelovim procesorima) i ova moja bi bila brža, ali pravljena za moju specijalnu namenu.

Code:
// File: Interval.h
#ifndef INTERVAL_H
#define INTERVAL_H

#include <pthread.h>
#include <fenv.h>

extern pthread_mutex_t roundingMutex;

class Interval
{
    long double lo, up;
    
    void lock()
    {
// Zaključavanja su kratka, ali konflikata ima često, pa uspavljivanje niti ne dolazi u obzir.
        while (pthread_mutex_trylock(&roundingMutex)) {
        }
    }
    
    void unlock()
    {
        pthread_mutex_unlock(&roundingMutex);
    }
public:
    Interval(long double value = 0) :
        lo(value),
        up(value)
    {
    }
    
    Interval(long double lower, long double upper) :
        lo(lower),
        up(upper)
    {
    }
// ...
    Interval operator +(Interval i)
    {
        lock();
        fesetround(FE_DOWNWARD);
        long double lower = lo + i.lo;
        fesetround(FE_UPWARD);
        long double upper = up + i.up;
// Sva racunanja bi bila u klasi, tako da restauriranje prethodnog stanja nije bitno.
        unlock();
        
        return Interval(lower, upper);
    }
// ...
};
// ...
#endif

// File: Interval.cpp
#include "Interval.h"

pthread_mutex_t roundingMutex = PTHREAD_MUTEX_INITIALIZER;

Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3453

Jabber: djoka_l


+1462 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 13:09 - pre 156 meseci
Neću da se pravim da razumem o čemu pišeš (intervalna algebra), ali sam pogledao malo dokumentaciju za Boost Interval biblioteku i nešto malo o tome kako se koriste FPU instrukcije.

Ono što mi je privuklo pažnju su add_up i add_down komande koje stižu uz Interval, a to je tačno ono što ti treba. Cela ta muka oko setovanja načina zaokruživanja je u stvari realizovana kroz gomilu _up i _down komnadi.

Stvar je u tome što pre FPU operacije treba da se isključi interapt, eventualno snimi kontekst, setuje Control registar, izvrše operacije, vrati kontekst i uključi interapt. Pretpostavljam da je to sve realizovano kroz te metode u asembleru, a ne onako kako ti pokušavaš da uradiš.

Nisam siguran da li su metode add_up i add_down thread safe, ali pokušaj da ih isprobaš.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
89.216.32.*



+2789 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost23.06.2011. u 13:52 - pre 156 meseci
Intervalna algebra? Vrlo prosta stvar. Svakoj funkciji se pridružuje funkcija , gde je skup svih zatvorenih intervala tako da za svako važi (ovde se pod podrazumeva tačna vrednost, a ne ono što računar izbaci, dok se pretpostavlja da ima tačnu mašinsku reprezentaciju). Poenta je da posle proizvoljno složenog računa kao rezultat dobiješ interval kome tačan rezultat garantovano pripada (tj. da kontrolišeš grešku računa).

Primera radi, ako brojevi i imaju tačnu reprezentaciju u računaru, onda je gde su i brojevi koji imaju tačnu reprezentaciju u računaru i izabrani tako da je i . Dakle, se računa kao sa FE_DOWNWARD zaokrugljivanjem, a kao sa FE_UPWARD zaokrugljivanjem.

boost-ova klasa Interval ima uslovno prevođenje koje zavisi od kompajlera i arhitekture, a na GNU prevodiocima koristi upravo ove funkcije. Pogledaj fajl boost/numeric/interval/detail/c99sub_rounding_control.hpp. Ja sam odatle i saznao za ove funkcije.

boost-ova klasa nije bezbedna za niti (što meni treba), ali vrši restauraciju načina zaokrugljivanja na prethodnu vrednost (što meni ne treba).
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

vlaiv
Vladimir Vlaisavljevic
Novi Sad

Član broj: 15993
Poruke: 352
*.dynamic.isp.telekom.rs.



+1 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost24.06.2011. u 09:32 - pre 156 meseci
Primetio sam da pricas o dve relativno nezavisne stvari i da ti jedna treba a druga ne.

Citat:
boost-ova klasa nije bezbedna za niti (što meni treba), ali vrši restauraciju načina zaokrugljivanja na prethodnu vrednost (što meni ne treba).


Znaci ako je parce koda bezbedno za niti, to znaci da sa dva razlicita threada ti mozes zvati to parce koda bez bojazni da ce doci do "pucanja" programa.
Ali to ne znaci da ne moras voditi racuna o nekim drugim stvarima kao sto je recimo trenutno stanje promenljive.

Zato se obicno uzima trenutno stanje globalne promenljive i pravi lokalna kopija za upotrebu u niti.

Tvoj slucaj je specifican zato sto je u pitanju registar procesora i ne mozes imati lokalne kopije (mislim mozes imati kopiju vrednosti ali ti ona
nista ne znaci kao vrednost, znaci kad je u registru).

Znaci kod tipa:

flag temp = trenutna_vrednost_flaga;
setuj_flag(zeljena_vrednost);
radi_operacije_koje_treba();
setuj_flag(temp);

Moze sam po sebi biti threadsafe u smislu da nece izazvati neki invalid pointer exception i slicno, odnosno mozes ga bezbedno zvati
i program ce se izvrsiti ali ne garantuje da ce ti rezultat biti tacan zato sto u radi_operacije_koje_treba() trenutku moze drugi thread
da setuje flag na drugu vrednost.

Jedini nacin da se izbegne ova korupcija podataka je sledece:

lock();
flag temp = trenutna_vrednost_flaga;
setuj_flag(zeljena_vrednost);
radi_operacije_koje_treba();
setuj_flag(temp);
unlock();

Ali vodi racuna da ce to u slucaju da nisi threadove rasporedio po procesorima da ti samo donese usporenje. Ako se threadovi
izvrsavaju na razlicitim procesorima u multiprocesorskoj masini onda ce biti ok sto se performansa tice (nece biti puno hitova na zakljucan kod)
i naravno vodi racuna da nemas 20 threadova na 2 procesora :D
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.3gnet.mts.telekom.rs.



+2789 Profil

icon Re: Podešavanje zaokrugljivanja i višenitnost25.06.2011. u 07:14 - pre 156 meseci
Digao sam mnogo buke niokočega. Evo šta kaže man pthread_create

Citat:
The new thread inherits the calling thread's floating-point environment (fenv(3)).


Dakle, svaka nit ima svoje podešavanje s tim da nova nit nasleđuje podešavanje od niti u kojoj je pozvana funkcija pthread_create. Samim tim je i boost-ova intervalna biblioteka bezbedna za niti.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

[es] :: Art of Programming :: Podešavanje zaokrugljivanja i višenitnost

[ Pregleda: 2393 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.