-
1. Data: 2012-03-31 16:15:42
Temat: dalsza optymalizacja
Od: " generał kenobi" <f...@W...gazeta.pl>
ten sposob rysowania rotowanej bitmapy jest fenomenalny
swoja prostota
for(int j=0; j<sprite_height; j++)
{
for(int i=0; i<sprite_width; i++)
{
SetPixel( x>>20, y>>20, sprite[j][i] );
x += dxdx; // skosy/ poprawki dla ruchu pixele na fiz ekranie
y += dydx; // dla ruchu po tekselach x++
}
x += dxdy; // skosy dla y++
y += dydy;
}
tu raczej nie da sie nic poprawic - ale chcialbym jakos moze
poprawic sama funkcje stawiania pixela
inline void SetPixelInDibInt(int x, int y, unsigned color)
{
int yc = CLIENT_Y-y;
if(!pBits) return;
if(yc<0) return;
if(yc>=CLIENT_Y) return;
if(x<0) return;
if(x>=CLIENT_X) return;
int adr = (yc*CLIENT_X+x);
((unsigned*)pBits)[adr] = color;
}
mam tutaj cala mase warunkow, zabezpieczajacych wprost przed
postawieniem pixela poza pamiecia ekranu - samo filtrowanie
sprite'ow robie bardzo zgrubne (odrzucam sprity o srodku iles tam
dalej poza ekranem ) tak ze przez to przechodzi cala masa
pixeli ze sprite'ow ktore sa tylko czesciowo w ekranie --
jak przerobic kod tej funkcji by bylo szybciej?
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
2. Data: 2012-04-01 12:23:11
Temat: Re: dalsza optymalizacja
Od: " " <f...@N...gazeta.pl>
=?ISO-8859-2?Q?_genera=B3_kenobi?= <f...@W...gazeta.pl> napisał(a):
> ten sposob rysowania rotowanej bitmapy jest fenomenalny
> swoja prostota
>
> for(int j=0; j<sprite_height; j++)
> {
> for(int i=0; i<sprite_width; i++)
> {
> SetPixel( x>>20, y>>20, sprite[j][i] );
>
> x += dxdx; // skosy/ poprawki dla ruchu pixele na fiz ekranie
> y += dydx; // dla ruchu po tekselach x++
> }
>
> x += dxdy; // skosy dla y++
> y += dydy;
> }
>
> tu raczej nie da sie nic poprawic - ale chcialbym jakos moze
> poprawic sama funkcje stawiania pixela
>
> inline void SetPixelInDibInt(int x, int y, unsigned color)
> {
>
> int yc = CLIENT_Y-y;
>
>
> if(!pBits) return;
>
> if(yc<0) return;
> if(yc>=CLIENT_Y) return;
>
> if(x<0) return;
> if(x>=CLIENT_X) return;
>
>
> int adr = (yc*CLIENT_X+x);
>
> ((unsigned*)pBits)[adr] = color;
>
> }
>
> mam tutaj cala mase warunkow, zabezpieczajacych wprost przed
> postawieniem pixela poza pamiecia ekranu - samo filtrowanie
> sprite'ow robie bardzo zgrubne (odrzucam sprity o srodku iles tam
> dalej poza ekranem ) tak ze przez to przechodzi cala masa
> pixeli ze sprite'ow ktore sa tylko czesciowo w ekranie --
>
> jak przerobic kod tej funkcji by bylo szybciej?
>
wychodzi na to ze wlasnie nalezaloby odwrocic proces - o ile
teraz jake po calej tekturze (a duza tekstura w prog2.exe ma 1000x1000
pixeli ) i czestokroc wypadam poza ekran to po obroceniu mozna
iterowac bez problemu po obruconej teksturze tylko w tym kawalku
ktory lezy w ekranie - tak ze to mogloby nawet przyspieszyc
(choc sa dodatkowe koszty albo zapisywania tych krawedzi dla sylwetki
albo iterowania po wiekszych kwadratach) - tak ze zarazem moze przyspieszyc
jak i moze zwolnic
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
3. Data: 2012-04-01 12:28:51
Temat: Re: dalsza optymalizacja
Od: " " <f...@N...gazeta.pl>
<f...@N...gazeta.pl> napisał(a):
> =?ISO-8859-2?Q?_genera=B3_kenobi?= <f...@W...gazeta.pl> napisał(a):
>
> > ten sposob rysowania rotowanej bitmapy jest fenomenalny
> > swoja prostota
> >
> > for(int j=0; j<sprite_height; j++)
> > {
> > for(int i=0; i<sprite_width; i++)
> > {
> > SetPixel( x>>20, y>>20, sprite[j][i] );
> >
> > x += dxdx; // skosy/ poprawki dla ruchu pixele na fiz ekranie
> > y += dydx; // dla ruchu po tekselach x++
> > }
> >
> > x += dxdy; // skosy dla y++
> > y += dydy;
> > }
> >
> > tu raczej nie da sie nic poprawic - ale chcialbym jakos moze
> > poprawic sama funkcje stawiania pixela
> >
> > inline void SetPixelInDibInt(int x, int y, unsigned color)
> > {
> >
> > int yc = CLIENT_Y-y;
> >
> >
> > if(!pBits) return;
> >
> > if(yc<0) return;
> > if(yc>=CLIENT_Y) return;
> >
> > if(x<0) return;
> > if(x>=CLIENT_X) return;
> >
> >
> > int adr = (yc*CLIENT_X+x);
> >
> > ((unsigned*)pBits)[adr] = color;
> >
> > }
> >
> > mam tutaj cala mase warunkow, zabezpieczajacych wprost przed
> > postawieniem pixela poza pamiecia ekranu - samo filtrowanie
> > sprite'ow robie bardzo zgrubne (odrzucam sprity o srodku iles tam
> > dalej poza ekranem ) tak ze przez to przechodzi cala masa
> > pixeli ze sprite'ow ktore sa tylko czesciowo w ekranie --
> >
> > jak przerobic kod tej funkcji by bylo szybciej?
> >
> wychodzi na to ze wlasnie nalezaloby odwrocic proces - o ile
> teraz jake po calej tekturze (a duza tekstura w prog2.exe ma 1000x1000
> pixeli ) i czestokroc wypadam poza ekran to po obroceniu mozna
> iterowac bez problemu po obruconej teksturze tylko w tym kawalku
> ktory lezy w ekranie - tak ze to mogloby nawet przyspieszyc
>
> (choc sa dodatkowe koszty albo zapisywania tych krawedzi dla sylwetki
> albo iterowania po wiekszych kwadratach) - tak ze zarazem moze przyspieszyc
> jak i moze zwolnic
>
troche sie zmeczylem ale wieczorem moze sprobuje (z ciekawosci czy
przyspieszy) uruchomic prostrsza wersji z odwrotna transformacja
(tj bez sylwetek)
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
4. Data: 2012-04-01 13:17:09
Temat: Re: dalsza optymalizacja
Od: " M.M." <m...@N...gazeta.pl>
<f...@N...gazeta.pl> napisał(a):
> <f...@N...gazeta.pl> napisał(a):
>
> > =?ISO-8859-2?Q?_genera=B3_kenobi?= <f...@W...gazeta.pl> napisał(a):
> >
> > > ten sposob rysowania rotowanej bitmapy jest fenomenalny
> > > swoja prostota
> > >
> > > for(int j=0; j<sprite_height; j++)
> > > {
> > > for(int i=0; i<sprite_width; i++)
> > > {
> > > SetPixel( x>>20, y>>20, sprite[j][i] );
> > >
> > > x += dxdx; // skosy/ poprawki dla ruchu pixele na fiz ekranie
> > > y += dydx; // dla ruchu po tekselach x++
> > > }
> > >
> > > x += dxdy; // skosy dla y++
> > > y += dydy;
> > > }
> > >
> > > tu raczej nie da sie nic poprawic - ale chcialbym jakos moze
> > > poprawic sama funkcje stawiania pixela
> > >
> > > inline void SetPixelInDibInt(int x, int y, unsigned color)
> > > {
> > >
> > > int yc = CLIENT_Y-y;
> > >
> > >
> > > if(!pBits) return;
> > >
> > > if(yc<0) return;
> > > if(yc>=CLIENT_Y) return;
> > >
> > > if(x<0) return;
> > > if(x>=CLIENT_X) return;
> > >
> > >
> > > int adr = (yc*CLIENT_X+x);
> > >
> > > ((unsigned*)pBits)[adr] = color;
> > >
> > > }
> > >
> > > mam tutaj cala mase warunkow, zabezpieczajacych wprost przed
> > > postawieniem pixela poza pamiecia ekranu - samo filtrowanie
> > > sprite'ow robie bardzo zgrubne (odrzucam sprity o srodku iles tam
> > > dalej poza ekranem ) tak ze przez to przechodzi cala masa
> > > pixeli ze sprite'ow ktore sa tylko czesciowo w ekranie --
> > >
> > > jak przerobic kod tej funkcji by bylo szybciej?
> > >
> > wychodzi na to ze wlasnie nalezaloby odwrocic proces - o ile
> > teraz jake po calej tekturze (a duza tekstura w prog2.exe ma 1000x1000
> > pixeli ) i czestokroc wypadam poza ekran to po obroceniu mozna
> > iterowac bez problemu po obruconej teksturze tylko w tym kawalku
> > ktory lezy w ekranie - tak ze to mogloby nawet przyspieszyc
> >
> > (choc sa dodatkowe koszty albo zapisywania tych krawedzi dla sylwetki
> > albo iterowania po wiekszych kwadratach) - tak ze zarazem moze przyspieszyc
> > jak i moze zwolnic
> >
>
> troche sie zmeczylem ale wieczorem moze sprobuje (z ciekawosci czy
> przyspieszy) uruchomic prostrsza wersji z odwrotna transformacja
> (tj bez sylwetek)
Jeśli już tak optymalizujesz, to powiedz mi czy warto zamienić
obliczenia z typu double na inta? W programie jest macierz kwadratowa.
Mieści się ona w całości L2. Powiedzmy że do losowych elementów tej
macierzy dodaję jedynki, coś w rodzaju:
for( dość dużo pętli )
macierz[ compute_row() * col_size + compute_col() ] ++ ;
Koszt wykonania compute_row i comute_col jest bardzo mały.
Potem inne obliczenia muszą być przeprowadzane na typie double, ale
ta inkrementacja może być wykonana na typie int. Warto zadeklarować
drugą macierz typu int i potem przekopiować do typu double? Czy
może operacje inc na typie double są równie szybkie?
Pozdrawiam
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
5. Data: 2012-04-01 13:29:50
Temat: Re: dalsza optymalizacja
Od: bartekltg <b...@g...com>
W dniu 2012-04-01 13:17, M.M. pisze:
>
> Jeśli już tak optymalizujesz, to powiedz mi czy warto zamienić
> obliczenia z typu double na inta? W programie jest macierz kwadratowa.
> Mieści się ona w całości L2. Powiedzmy że do losowych elementów tej
> macierzy dodaję jedynki, coś w rodzaju:
>
> for( dość dużo pętli )
> macierz[ compute_row() * col_size + compute_col() ] ++ ;
>
> Koszt wykonania compute_row i comute_col jest bardzo mały.
> Potem inne obliczenia muszą być przeprowadzane na typie double, ale
> ta inkrementacja może być wykonana na typie int. Warto zadeklarować
> drugą macierz typu int i potem przekopiować do typu double? Czy
> może operacje inc na typie double są równie szybkie?
Dobrze rozumiem, chcesz
x<-x+1
zamienić na
i<-int(x)
i<-i+1
x<-double(i)
Musiałyby się dziać cuda, aby to było szybsze (czy już
jedna konwersja nie będzie dłuższa niż dodanie?)
ale po prostu sprawdź.
BTW, zerknij na to
http://stereopsis.com/FPU.html
pzdr
bartekltg
-
6. Data: 2012-04-01 13:58:46
Temat: Re: dalsza optymalizacja
Od: " M.M." <m...@N...gazeta.pl>
bartekltg <b...@g...com> napisał(a):
> W dniu 2012-04-01 13:17, M.M. pisze:
>
> >
> > JeĹli juĹź tak optymalizujesz, to powiedz mi czy warto zamieniÄ
> > obliczenia z typu double na inta? W programie jest macierz kwadratowa.
> > MieĹci siÄ ona w caĹoĹci L2. Powiedzmy Ĺźe do losowych elementĂłw tej
> > macierzy dodajÄ jedynki, coĹ w rodzaju:
> >
> > for( doĹÄ duĹźo pÄtli )
> > macierz[ compute_row() * col_size + compute_col() ] ++ ;
> >
> > Koszt wykonania compute_row i comute_col jest bardzo maĹy.
> > Potem inne obliczenia muszÄ byÄ przeprowadzane na typie double, ale
> > ta inkrementacja moĹźe byÄ wykonana na typie int. Warto zadeklarowaÄ
> > drugÄ macierz typu int i potem przekopiowaÄ do typu double? Czy
> > moĹźe operacje inc na typie double sÄ rĂłwnie szybkie?
>
>
>
> Dobrze rozumiem, chcesz
>
> x<-x+1
>
> zamieniÄ na
>
> i<-int(x)
> i<-i+1
> x<-double(i)
>
> MusiaĹyby siÄ dziaÄ cuda, aby to byĹo szybsze (czy juĹź
> jedna konwersja nie bÄdzie dĹuĹźsza niĹź dodanie?)
> ale po prostu sprawdĹş.
Raczej tak:
double x[1000];
for( i=0 ; i<1000000 ; i++ )
x[rand()%size] ++;
Na:
int tmp[1000];
for( i=0 ; i<1000000 ; i++ )
tmp[rand()%size] ++;
double x[1000];
for( i=0 ; i<1000 ; i++ )
x[i] = (double)tmp[i];
Dłuższe obliczenia na intach i potem jedna konwersja na doubla.
Problem w tym że obliczenia na intach są trywialne, tylko inkrementacja.
Pozdrawiam
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
7. Data: 2012-04-01 13:59:54
Temat: Re: dalsza optymalizacja
Od: " " <f...@N...gazeta.pl>
> > > > ten sposob rysowania rotowanej bitmapy jest fenomenalny
> > > > swoja prostota
> > > >
> > > > for(int j=0; j<sprite_height; j++)
> > > > {
> > > > for(int i=0; i<sprite_width; i++)
> > > > {
> > > > SetPixel( x>>20, y>>20, sprite[j][i] );
> > > >
> > > > x += dxdx; // skosy/ poprawki dla ruchu pixele na fiz ekranie
> > > > y += dydx; // dla ruchu po tekselach x++
> > > > }
> > > >
> > > > x += dxdy; // skosy dla y++
> > > > y += dydy;
> > > > }
> > > >
> > > > tu raczej nie da sie nic poprawic - ale chcialbym jakos moze
> > > > poprawic sama funkcje stawiania pixela
> > > >
> > > > inline void SetPixelInDibInt(int x, int y, unsigned color)
> > > > {
> > > >
> > > > int yc = CLIENT_Y-y;
> > > >
> > > >
> > > > if(!pBits) return;
> > > >
> > > > if(yc<0) return;
> > > > if(yc>=CLIENT_Y) return;
> > > >
> > > > if(x<0) return;
> > > > if(x>=CLIENT_X) return;
> > > >
> > > >
> > > > int adr = (yc*CLIENT_X+x);
> > > >
> > > > ((unsigned*)pBits)[adr] = color;
> > > >
> > > > }
> > > >
> > > > mam tutaj cala mase warunkow, zabezpieczajacych wprost przed
> > > > postawieniem pixela poza pamiecia ekranu - samo filtrowanie
> > > > sprite'ow robie bardzo zgrubne (odrzucam sprity o srodku iles tam
> > > > dalej poza ekranem ) tak ze przez to przechodzi cala masa
> > > > pixeli ze sprite'ow ktore sa tylko czesciowo w ekranie --
> > > >
> > > > jak przerobic kod tej funkcji by bylo szybciej?
> > > >
> > > wychodzi na to ze wlasnie nalezaloby odwrocic proces - o ile
> > > teraz jake po calej tekturze (a duza tekstura w prog2.exe ma 1000x1000
> > > pixeli ) i czestokroc wypadam poza ekran to po obroceniu mozna
> > > iterowac bez problemu po obruconej teksturze tylko w tym kawalku
> > > ktory lezy w ekranie - tak ze to mogloby nawet przyspieszyc
> > >
> > > (choc sa dodatkowe koszty albo zapisywania tych krawedzi dla sylwetki
> > > albo iterowania po wiekszych kwadratach) - tak ze zarazem moze
przyspieszyc
>
> > > jak i moze zwolnic
> > >
> >
> > troche sie zmeczylem ale wieczorem moze sprobuje (z ciekawosci czy
> > przyspieszy) uruchomic prostrsza wersji z odwrotna transformacja
> > (tj bez sylwetek)
>
> Jeśli już tak optymalizujesz, to powiedz mi czy warto zamienić
> obliczenia z typu double na inta? W programie jest macierz kwadratowa.
> Mieści się ona w całości L2. Powiedzmy że do losowych elementów tej
> macierzy dodaję jedynki, coś w rodzaju:
>
> for( dość dużo pętli )
> macierz[ compute_row() * col_size + compute_col() ] ++ ;
>
> Koszt wykonania compute_row i comute_col jest bardzo mały.
> Potem inne obliczenia muszą być przeprowadzane na typie double, ale
> ta inkrementacja może być wykonana na typie int. Warto zadeklarować
> drugą macierz typu int i potem przekopiować do typu double? Czy
> może operacje inc na typie double są równie szybkie?
>
swego czasu opisywalem jak to podmienienie literalnie czterech
instancji floatow na inty przyspieszyla mi program 2 razy
wyzej bylo opisane jak to przerobienie paru (tez cos kolo czterech
floatow na inty przyspieszylo mi program mw 5 razy - ( 8-9 razy
w stosunku do wersji pierwotnej ktora pozniej przyspieszyla ok 30%
i dopiero przepisanie na fixed pointy to przyspieszylo dalsze ok 5
razy)
z tego co sie orientuje to co tak zarzyna kompa to konwersje
z floata na int - nie jest to dla mnie jasne ale niejaki gourley
w tutku o dynamice plynow (kiedys wspominalem i cytowalem) ppisze
ze aby dokonac przyciecia z floata na inta kompilatory c przelaczaja
tryb fbu - i to chyba to jest problemem
tak czy owak to ze przepisanie paru floatow na fixedpointy przyspieszylo
mi kod z miejsca >5 razy daje do myslenia nt tego by jednak sprawdzac
czy na fxintach to nie ruszy przypadkiem z kopyta
tak naprawde moze to byc jednak nie tyle wina floatow tylko wlasnie tej
konwersji z floata na int - u mnie obliczenia koncza sie jako koordynaty
dla setpixela wiec musza byc calkowite wiec pozostawaloby albo przepisywac
na fixedpointy albo nauczyc sie jakiegos innego sposobu konwersji z inta
na float (tam chodzi chyba o to ze domyslnie dla fpu jest zaokraglanie
a c wymusza obcinanie w dol i to powoduje ze w kolko przelacza tryb fpu
- glupota maksymalna, trzeba sie tym wiecej zainteresowac)
jesli jest tak wlasnie to po prostu moze byc tak ze kazda konwersja
z floata na int to totalny zarzynacz wydajnosci i nalezaloby sie
wogole tego pozbyc (moze jest jakas inna metoda konwersji ktora nie
daje takiej katastrofy)
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
8. Data: 2012-04-01 14:20:09
Temat: Re: dalsza optymalizacja
Od: bartekltg <b...@g...com>
W dniu 2012-04-01 13:58, M.M. pisze:
>
> Raczej tak:
> double x[1000];
> for( i=0 ; i<1000000 ; i++ )
> x[rand()%size] ++;
>
> Na:
tutaj jeszcze konwersja w drugą stronę.
> int tmp[1000];
> for( i=0 ; i<1000000 ; i++ )
> tmp[rand()%size] ++;
>
> double x[1000];
> for( i=0 ; i<1000 ; i++ )
> x[i] = (double)tmp[i];
>
> Dłuższe obliczenia na intach i potem jedna konwersja na doubla.
> Problem w tym że obliczenia na intach są trywialne, tylko inkrementacja.
I co Cię powstrzymuje przed odpaleniem tego z pomiarem czasu;)
BTW, http://www.youtube.com/watch?v=gENVB6tjq_M
Chcesz rozdać milion kulek w tysiąc otworków.
To tego wystarczy ~1000 losowań i tyle dodawań
(+ coś tego rzędu obliczeń związanych z rozkładem
Poissona), a pewnie da się i lepiej.
Podpowiadać dalej?
pzdr
bartekltg
-
9. Data: 2012-04-01 14:21:06
Temat: Re: dalsza optymalizacja
Od: bartekltg <b...@g...com>
W dniu 2012-04-01 14:20, bartekltg pisze:
> W dniu 2012-04-01 13:58, M.M. pisze:
>
>>
>> Raczej tak:
>> double x[1000];
>> for( i=0 ; i<1000000 ; i++ )
>> x[rand()%size] ++;
>>
>> Na:
>
> tutaj jeszcze konwersja w drugą stronę.
>
>> int tmp[1000];
>> for( i=0 ; i<1000000 ; i++ )
>> tmp[rand()%size] ++;
>>
>> double x[1000];
>> for( i=0 ; i<1000 ; i++ )
>> x[i] = (double)tmp[i];
>>
>> Dłuższe obliczenia na intach i potem jedna konwersja na doubla.
>> Problem w tym że obliczenia na intach są trywialne, tylko inkrementacja.
>
> I co Cię powstrzymuje przed odpaleniem tego z pomiarem czasu;)
>
> BTW, http://www.youtube.com/watch?v=gENVB6tjq_M
>
> Chcesz rozdać milion kulek w tysiąc otworków.
> To tego wystarczy ~1000 losowań i tyle dodawań
> (+ coś tego rzędu obliczeń związanych z rozkładem
> Poissona), a pewnie da się i lepiej.
...raczej dwumianowym. Wszytko jedno;)
>
> Podpowiadać dalej?
>
pzdr
bartekltg
-
10. Data: 2012-04-01 15:07:21
Temat: Re: dalsza optymalizacja
Od: " M.M." <m...@N...gazeta.pl>
bartekltg <b...@g...com> napisał(a):
> W dniu 2012-04-01 13:58, M.M. pisze:
>
> >
> > Raczej tak:
> > double x[1000];
> > for( i=0 ; i<1000000 ; i++ )
> > x[rand()%size] ++;
> >
> > Na:
>
> tutaj jeszcze konwersja w drugÄ stronÄ.
>
> > int tmp[1000];
> > for( i=0 ; i<1000000 ; i++ )
> > tmp[rand()%size] ++;
> >
> > double x[1000];
> > for( i=0 ; i<1000 ; i++ )
> > x[i] = (double)tmp[i];
> >
> > DĹuĹźsze obliczenia na intach i potem jedna konwersja na doubla.
> > Problem w tym Ĺźe obliczenia na intach sÄ trywialne, tylko inkrementacja.
>
> I co CiÄ powstrzymuje przed odpaleniem tego z pomiarem czasu;)
>
> BTW, http://www.youtube.com/watch?v=gENVB6tjq_M
>
> Chcesz rozdaÄ milion kulek w tysiÄ c otworkĂłw.
> To tego wystarczy ~1000 losowaĹ i tyle dodawaĹ
> (+ coĹ tego rzÄdu obliczeĹ zwiÄ zanych z rozkĹadem
> Poissona), a pewnie da siÄ i lepiej.
>
> PodpowiadaÄ dalej?
Chyba zakręciłem totalnie jaka jest istota problemu i nikt
nie zrozumiał, sorry :D
Chyba mogłem zapytać prościej: czy inkrementacja intów jest
szybsza od inkrementacji doubli? Dane są wybierane w przybliżeniu
z losowych adresow w pamięci, czyli nie chodzi o inkrementację jednej
zmiennej ktora jest ciagle w rejestrze procesora. Tablice z danymi
mieszcza sie w L2, ale nie mieszcza sie w L1.
Pozdrawiam
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/