Pokaż wiadomości

Ta sekcja pozwala Ci zobaczyć wszystkie wiadomości wysłane przez tego użytkownika. Zwróć uwagę, że możesz widzieć tylko wiadomości wysłane w działach do których masz aktualnie dostęp.


Wiadomości - bad80

Strony: [1] 2
1
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 16, 2012, 12:26:17 »
Mi to wygląda jak rysowanie po jakimś ekranie. W takim przypadku to prawdopodobnie nie bawił bym się we floaty, tylko to przerobił na obliczenia stałoprzecinkowe i/lub zastosował jeden ze znanych algorytmów rysowania tego co tam potrzeba. :)

Nie w tym problem;-), zrobilem na fixedpointach ale nie chce spisywac calego fpu na straty - bo dziala przyzwoicie potrzebna jest tylko normalnie dzialajaca konwersja

2
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 16, 2012, 11:16:44 »
Nie jest to kwestia niszowa, więc wiedziałem. A co do podejścia: olewam, dopóki rzeczywiście nie stanie się to krytycznym punktem. Wtedy bym się zastanowił i najprawdopodobniej
wpisał wstawkę w asm (używającą po prostu instrukcji FISTP + modyfikacja algorytmu żeby działał przy zaokrąglaniu) albo zainteresował się właśnie SSE.

no ja moge potwierdzic ze roznica zwiazana z tym potrafi byc spora jast roznica miedzy np 20 fps a 100 fps a jeden z programikow po wywaleniu tego z petli mw o tyle mi skoczyl

a dałbyś rade może zilustrowac tu tą wstawkę dla np

float x = 1.7, y = 1.3;

mem[(int)y][(int)x]=0x00baddee;

?


float x = 1.7, y = 1.3;

asm {

      ??
    ??????
     ??
 }

mem[y][x]=0x00baddee;

ew sztuczki zapodane pod jednym z wymienionych linkow wydawalybymi sie do uzycia

Cytuj
int FloatToInt(float x)

{

       unsigned e = (0x7F + 31) - ((* (unsigned*) &x & 0x7F800000) >> 23);

       unsigned m = 0x80000000 | (* (unsigned*) &x << 8);

       return int((m >> e) & -(e < 32));

}

lub


Cytuj
You can do Nils' trick safely for any float up to (but not including) 16777216. If you want a full positive int, use a double
unsigned ftoi(double d)
{
    d += 4503599627370496.0;  // 1 << 52
    return (unsigned &)d;
}

C++ addict
Currently working on: the 3D engine for Tomb Raider.

lub

Cytuj
#include <intrin.h>

int FloatToInt_SSE(float x)

{

       return _mm_cvt_ss2si( _mm_load_ss(&x) );

}

nie sprawdzalem czy dziala, moim fawortyem bylaby wersja z
d+= bo uzywam starego kompilatora

ale tak naprawde wszystko to wydaje mi sie nie do konca
porzadnym rozwiazaniem problemu - ktory mz nalezaloby rozwiazac przelaczajac na stele kompilator do trybu przycinania
i spowodowac by ( (int) float ) nie przelaczalo tego z powrotem

nie kojarzysz moze jaki moze byc powod przelaczania na zaokraglanie za kazdym razem - do czego jest potrzebny tryb
z zaokraglaniem utrzymywany na fpu - zakladam ze to zaokraglanie dotyczy tylko przypadku konwersji z floatow do intow a nie jakichs dzialan na floatach


3
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 16, 2012, 08:30:02 »
Biorąc pod uwagę, że ceil() i floor() też muszą wewnętrznie przełączać zaokrąglanie, to z deszczu pod rynnę. ;)

a wogole, mozesz wypowiedziec sie o tej 'katastrofie' f->i ?
wiedziales o tym? jak podszedlbys do tego problemu?

(w tym miejscu moge pozdrowic grupowiczow gynvaela c, xiona i rega - czytalem wasze teksty - fenomenalnie (vel dosyc dobrze) piszecie)

4
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 16, 2012, 08:25:55 »
Zacząłbym od ,,Intel® 64 and IA-32 Architectures Optimization Reference Manual'', dostępnej oczywiście na stronie Intela. W szczególności ta optymalizacja o której pisze KrzysieK to ,,store-to-load forwarding'' (albo krócej ,,store forwarding''). W ww. jest cały rozdział poświęcony optymalizacji FPU i zaokrąglaniu. A konkluzja jest prosta: ,,włącz pan SSE i przestań zawracać głowę''.

konkluzja, ale czy nie prostacka? jak 'włacze' sse to czy kazdy f->i bedzie konwertowany na sse? Czy wtedy mieszanie kodu sse i fpu nie powoduje podobnego rodzaju opoznien zwiazanych z przelaczaniem jednego na drugie?

5
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 22:23:18 »
Dziwadło pochodzi z disassembly MSVC kodu pętli, która iteruje po liczbach typu int i konwertuje je do float - podobnie jak w przykładach już podanych w temacie. Nie wiem z czego wynika

ja moge przypomniec ze  (float) int nie stanowi problemu
<osobiscie chwilowo odloze ten temat bo nie mam nawet sily na czytanie z google troche choruje i czasem sie czuje gorzej niz zwykle> (jak wlasnie teraz, wzialem wczoraj niedobre lekarstwo i cos mnie pali i swedzi w wątrobie tak ze zaczynam sie bac by sie od tego nei przekrecic (przesada ale zawsze))

6
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 17:52:33 »
Ten kod to doskonały przykład na to, jak można ugrząść w mikrooptymalizacjach i narzekać że konwersja float->int staje się bottleneckiem, podczas gdy w rzeczywistości cały algorytm jest do kitu, bo to samo można zrealizować dużo szybciej na samych intach:

http://en.wikipedia.org/wiki/Midpoint_circle_algorithm

Zacytowałbym tu takie słynne stwierdzenie Dijkstry...

to nie byl przyklad na rysowanie kola, to byl przyklad na

                                      m[(int)y][(int)x] = c;

zaloz ze akurat potrzebujesz wyliczac x i y na floatach -
ta linijka bedzie niemilosiernie mulic (na moje oko jakies 140 ns
wzgledem jakichs moze 10 ns (moze mniej) w normalnej wersji

//edit
zmierzcie sobie tam co poniektorzy ej wy tam stamtąd i porownajcie dla jakiejst tablicy typu 1000x1000 albo 100 x 100x100 to mi powiecie (ja nie mam teraz sily - ale wczesniej mierzylem i wiem ze u mnie to b. mulilo )

[a bardzo chetnie sie dowiem jak to sie przedstawia na innych niz moj prockach]
--
sound: davis miles

7
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 17:40:30 »
Jak zaokrąglić? Nie wiem, #include <cmath> i round()? Powinno się skompilować do czegoś ładnego.

Ztcw nie ma funkcji round() w c/c++,
Pozatym ceil() i floor() zwracają floaty/double a nie inty.
Pozniej nawet skonwertowanie 17.0 do 17 bedzie trwalo tak samo dlugo.

Gdyby byla funkcja

int round(float)

to kompilatory ewentualnie moglyby wnioskowac z kontekstu i
generowac co trzeba,

mz bug polega na tym ze fpu niepotrzebnie 'chce' z jakichs powodow miec bez przerwy ustawiony stan zaokraglania - nie wiem do czego mu to jest potrzebne - gdy tymczasem program w c na odwrot potrzebuje wylacznie stanu przycinania - jest to debilizm, nie wiem z czego to moze wynikac, czy z tego ze
programy 'w innych jezykach' uzywaja zaokraglania wiec oczekuja ze fpu zaokragla a c musi sobie przelaczac i zwracac

[to co prawda rzczej nie ma sensu - bo przy przelaczaniu na inny watek stan fpu na pewno i tak jest zapisywany -- pytanie wiec na czylje potrzeby kompilator c przelacza z powrotem fpu na zaokraglanie jesli nie na swoje a jesli na swoje to czemu skoro zawsze przycina a nigdy nie zaokragla?]


blad mz polega na tym ze powinny byc w fpu dostepne po prostu rownolegle obie komendy i przycinanie i zaokraglanie - inna dziwna rzecz ze malo ludzi o tym mam wrazenie wie - dyskutuja w napuszony sposob o optymalizacjach ze nie mam sensu uzywac asma itp a tu spoczywa taka kwestia jak ta




8
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 17:18:13 »
Hej, a skoro konwersja int/float jest wolniejsza niż powinna bo procesor musi przełączyć się z zaokrąglania na przycinanie, to dlaczego po prostu nie zaokrąglić?

a jak zaokraglic floata do inta w c?

9
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 16:38:49 »
Trefny przykład.
Tak się okręgu nie rysuje bo będzie dziurawe. :)
A da się narysować to poprawnie praktycznie bez rzutowania flotat<->int.... thehe.

to nie jest przyklad na rysowanie okregu tylko ilustracja
kiedy mozesz potrzebowac wydajnej konwersji z float a na int - mozna sobie obliczac trajektorie jakichs bezierow i raczej nalezaloby nie spisywac fpu na straty i rysowac je pozniej w ramie - albo inne przypadki - konwersja z float na int jest czesto uzywana (sam nie mam pewnosci czy niejawne rzutowania z c nie wywoluja mi tego czesciej niz bym chcial)

// edit - moze byc np gesta spirala wiec bedzie duzo pixeli
// wlasnie float to int zarżnie calosc mw 2 razy - tylko dwa bo
// sin cos sa mw tak samo wolne

  radius=0.0;
  angle =0.0;

for(int i=0;;i++)
{
 
  radius += 3.0/360.0;
  angle +=  1.0/2.0/3.14159/radius;

   if(radius>500.0) break;

  float x =  ox + radius* cos( angle );
  float y =  oy + radius* sin( angle  );

  pixelbufor[(int)y][(int)x] = color;

}

pewnie daloby sie bez sin cos i na fixedpointach ale trzeba pokombinowac a nie chodzi mi tu akurat o stawianie tezy ze wszystko nawet dzis telpiej jest pisac na intach  tylko ze jak ktos chce to zrobic na floatach to musi  sobie 'jakos' poradzic z bugiem we float to int

--
guosniki: miles davis

10
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 16:09:51 »
Z tego co ja rozumiem, to konwersje int<->float mogą być wolne również z powodu LHS (load-hits-store), przynajmniej na x87 - instrukcja x86 zapisuje inta do pamięci, instrukcja x87 wczytuje z tego miejsca (może z konwersją) wartość na stos floatów, a między nimi trochę straconych cykli z powodu pipeline flush.
SSE z tego co widzę ma instrukcje do bezpośredniego przerzucania wartości rejestr int <-> rejestr SSE wraz z konwersją.

nie ma problemu z i->f (u mnie 3-4 ns )

to sie bierze z przelaczania jakiegos stanu fpu - nie bardzo rozumiem skad sie bierze potrzeba przelaczania tego wiele razy - bo wychodzi chyba na to ze to jest przelaczane w ta i spowrotem dla _kazdego_ f->i, o ile wszystkie konwersje z f->i sa w c robione z obcinaniem to wydaje sie ze wystarczyloby to tylko tak wlaczyc i koniec (?)

//edit

rozumiem potrzebe przelaczania tego ale nie rozumiem potrzeby przelaczania tego za kazdym konwertowaniem

na intelowskiej stronce jest napisane

The problem with casting from floating-point numbers to 32-bit integers stems from the ANSI C standard, which states the conversion should be effected by truncating the fractional portion of the number and retaining the integer result. Because of this, whenever the Microsoft Visual C++ 6.0 compiler encounters an (int) or a (long) cast, it inserts a call to the _ftol C run-time function. This function modifies the floating-point rounding mode to 'truncate', performs the conversion, and then resets the rounding mode to its original state prior to the cast. This code sequence is a detriment to application performance because modifying the rounding mode requires use of the long-latency FLDCW (Floating Point Load Control Word) instruction.

dalej jest zalecany by uzyc jednej funkcji z float.h
(kiedys spróbuje i zobacze co wyjdzie)

(nie wiem czy problem dotyczy tylko starych prockow i kompilatorow czy wszystkich)

//edit link do oryginalnej stronki gourleya

http://software.intel.com/en-us/articles/fluid-simulation-for-video-games-part-5/

kod potrzebny do f-i (zdaje sie ze na nowszym kompilatorze i procku)

004066F2  fld         dword ptr [esp+0Ch]        // Push vIdx.y onto FPU stack
004066F6  fnstcw      word ptr [esp+2]           // Store FPU control word onto runtime stack
004066FA  movzx       eax,word ptr [esp+2]       // eax = FPU control word
004066FF  or          ah,0Ch                     // Set FPU control word to truncation mode
00406702  mov         dword ptr [esp+4],eax      // Save new control word onto runtime stack
00406706  fldcw       word ptr [esp+4]           // Load new control word
0040670A  fistp       dword ptr [esp+4]          // Convert float to int and pop FPU stack
0040670E  mov         ecx,dword ptr [esp+4]       // ecx = integer
00406712  mov         dword ptr [edx+4],ecx      // Store integer
00406715  fldcw       word ptr [esp+2]          // Restore original FPU control word

koszmar imo

11
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 15:41:21 »
Chwila google'owania pokazuje ze dwie ścieżki, które można by obadać:
- Tutaj jest dyskusja na temat używania alternatywnych funkcji konwersji - instrukcja CVTTSS2SI  (z SSE) albo przełącznik /Qifist Visuala.
- Tutaj jest z kolei sztuczka wynikająca ze specyfikacji floatów IEEE. Akurat tam jest podana przy ograniczeniach < 256, ale jeśli będziesz się bawił także mantysą to możesz i dla większych coś podobnego osiągnąć.

ok, to juz jest cos, ta sztuczka zwlaszcza, pobadam
to - (choc mogloby to byc dla wiekszego zakresu najlepiej
cos kolo 20 bitow, znalazl ktos moze cos takiego? -
temat jest tak naprawde mz niezwykle wazny, po
wywaleniu niektorych f->i moje programy potrafily
przyspieszyc 2-8 razy




12
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 15:30:01 »
Olej inta. :)

żartowac (nt nie miesznia intow i floatow) to sobie mozna, ale jest to rodzaj fatalnego buga, który nie powinien występować

MUSI nie wystepowac o ile to ma byc normalne programowanie,

1) chcialbym wiedziec jak to moge ominac (wtedy kiedy potrzebuje skonwertowac floata do inta - moze byc zaokraglanie)

2) ten problem powinien zostac rozwiazany, chcialbym wiedziec jak naprawde mozna rozwiazac ten problem i o co tu chodzi

13
C++ / Odp: (int) float katastrofa
« dnia: Kwiecień 15, 2012, 15:20:35 »
A dlaczego potrzebujesz rzutować? Żeby obciąć część ułamkową? Żeby indeksować tablicę? Ze względu na zewnętrzne biblioteki? Myślę, że można poszukać tricków, ale trzeba wiedzieć po co się to robi :-)

A da się na poziomie asma "zrzutować floata na inta" bez przełączania trybu? Jeśli wiesz, że zaokrąglanie da ten sam wynik co obcinanie, to po co przełączać...

Liosan

na przyklad niech to bedzie stawienie pixela w ram buforze

unsigned color = 0x00e0b000;

for(int i=0; i<360; i++)
{

  float x =  320.0 + 230 * cos( i * degree360 );
  float y =  240.0 + 230 * sin( i * degree360 );

  pixelbufor[(int)y][(int)x] = color;

}

czy cos w tym stylu (nie umieszczam znacznikow do kodu
bo macie tu z tym totalny koszmar, [edit: szczerze mówiac i sam tekst tutaj wyglada beznadziejnie, powinien byc lepszy font np ms line draw])

Jak najbardziej moglbym nie obcinac tylko zaokraglac, ale jak to zrobic z poziomu c?


14
C++ / (int) float katastrofa
« dnia: Kwiecień 15, 2012, 14:35:09 »
Żeby pogadac o czyms sensowniejszym (bardziej technicznym)

Pewnego dnia przegladalem sobie pewne tutoriale dot.robienia symulacji płynów, jest to na stronkach intela, troche dla mnie za zaawansowana, autor który to napisał nazywa sie Gourley

Jest tam napisane że w kompilatorach c/c++ (ew w procesorach') nie wiem czy wszystkich i jak sie ta sprawa ma) jest pewnego rodzaju 'bug' polegajacy na tym ze zeby zrobić rzutowania z floata do inta, fpu musi byc przelaczane z trybu zaokraglania w tryb obcinania - to trwa masakrycznie dlugo

niedlugo pozniej odkrylem ze tak faktycznie jest - u mnie na dosyc starym procku takie rzutowanie trwa 60n i jest to wiecej niz zajmuje np cale kilkanascie linijek kodu zoptymalizowanej petli - jest to totalny kiler wydajnosci, absolutna katastrofa

1) ktos zna ten problem?
2) ktos kojarzy  jakich sytuacji  to dotyczy - nie jestem pewien czy dotyczy to wszystkich kompilatoro i x86
3) jak to rozwiazac (czasem zrzutowac na floata trzeba (*) - czy jest jakis sposob ominiecia tego, albo jakies sposob rozwiazania albo chocby jakis trick

 edit: ERRATA:

(*) z floata na inta - dotyczy to   [  f -> i  ]

(konwersja z int na float trwa normalnie czyli w ta strone jest okolo 20x szybciej)



15
Sprzedam / Odp: Sprzedam pomysł na grę
« dnia: Kwiecień 15, 2012, 14:04:17 »

każda droga zaczyna się od pierwszego kroku prawda ?

ściśle rzecz biorąc to niekoniecznie,    , ok sam musze sie wziac do roboty - bo prawde rzecz biorac to nie lubie rozmow na nietechniczne tematy

Strony: [1] 2