2013-03-06 11 views
5

Mam kod, który wywołuje wiele_ftol2_sse, czy są szybsze opcje?

int myNumber = (int)(floatNumber); 

który odbywa się w sumie około 10% mojego czasu procesora (zgodnie z profilera). O ile mogłem pozostawić go na tym, zastanawiam się, czy są szybsze opcje, więc próbowałem wyszukiwanie wokół, i natknęliśmy się na

http://devmaster.net/forums/topic/7804-fast-int-float-conversion-routines/ http://stereopsis.com/FPU.html

Próbowałem realizacji funkcji podane tam Real2Int() , ale daje złe wyniki i działa wolniej. Teraz zastanawiam się, czy istnieją szybsze implementacje wartości double/float floor do liczb całkowitych, czy też wersja SSE2 jest tak szybka, jak to tylko możliwe? Strony, które znalazłem, są trochę aktualne, więc może to być po prostu nieaktualne, a nowsze STL są szybsze.

Obecna implementacja robi:

013B1030 call  _ftol2_sse (13B19A0h) 

013B19A0 cmp   dword ptr [___sse2_available (13B3378h)],0 
013B19A7 je   _ftol2 (13B19D6h) 
013B19A9 push  ebp 
013B19AA mov   ebp,esp 
013B19AC sub   esp,8 
013B19AF and   esp,0FFFFFFF8h 
013B19B2 fstp  qword ptr [esp] 
013B19B5 cvttsd2si eax,mmword ptr [esp] 
013B19BA leave 
013B19BB ret 

Podobne pytania znalazłem:

Fast float to int conversion and floating point precision on ARM (iPhone 3GS/4)

What is the fastest way to convert float to int on x86

Ponieważ oba są stare, lub są ARM, I Zastanawiam się, czy są aktualne sposoby na zrobienie tego. Zauważ, że mówi, że najlepszą konwersją jest ta, która się nie zdarza, ale muszę ją mieć, aby nie było to możliwe.

Odpowiedz

6

To będzie trudne do pokonania, jeśli celujesz w standardowy sprzęt x86. Środowisko wykonawcze nie ma pewności, że docelowa maszyna ma jednostkę SSE. Jeśli tak, to może zrobić to, co robi kompilator x64 i wstawić kod operacji cvttss2si. Ale ponieważ środowisko wykonawcze musi sprawdzić, czy jednostka SSE jest dostępna, pozostaje aktualna implementacja. Tak właśnie działa implementacja ftol2_sse. Co więcej, przekazuje wartość w rejestrze x87, a następnie przekazuje ją do rejestru SSE, jeśli dostępna jest jednostka SSE.

Można powiedzieć kompilatorowi x86, aby kierował reklamy na maszyny z jednostkami SSE. Wówczas kompilator rzeczywiście emitowałby wbudowany kod kreskowy cvttss2si. To będzie tak szybko, jak to tylko możliwe. Ale jeśli uruchomisz kod na starszej maszynie, to zawiedzie. Być może możesz dostarczyć dwie wersje, jedną dla maszyn z SSE, i jedną dla tych bez.

To nie przyniesie Ci tak wiele. Po prostu uniknie się całego obciążenia związanego z ftol2_sse, co dzieje się, zanim dojdziesz do kodu operacyjnego cvttss2si, który wykonuje pracę.

Aby zmienić ustawienia kompilatora z IDE, użyj Project> Properties> Configuration Properties> C/C++> Generowanie kodu> Włącz ulepszony zestaw instrukcji. W linii poleceń jest to/arch: SSE lub/arch: SSE2.

+0

idealny, kod x64 działa znacznie szybciej! – SinisterMJ

1

Dla double Nie sądzę, będzie w stanie poprawić wyniki dużo, ale jeśli masz dużo float s do konwersji, że przy użyciu zapakowany konwersji może pomóc, oto kod nasm:

global _start 

section .data 
    align 16 
    fv1: dd 1.1, 2.5, 2.51, 3.6 

section .text 
    _start: 

    cvtps2dq xmm1, [fv1] ; Convert four 32-bit(single precision) floats to 32-bit(double word) integers and place the result in xmm1 

Powinien istnieć kod wewnętrzny, który pozwala zrobić to samo w łatwiejszy sposób, ale nie jestem zaznajomiony z używaniem bibliotek wewnętrznych. Chociaż nie korzystasz z gcc, ten artykuł Auto-vectorization with gcc 4.7 jest otwieraczem oczu na temat tego, jak trudno jest uzyskać kompilator generujący dobry wektorowy kod.

1

Jeśli potrzebujesz prędkości i dużej bazy maszyn docelowych, lepiej wprowadź szybką wersję SSE wszystkich swoich algorytmów, a także wersję ogólną - i wybierz algorytmy do wykonania na znacznie wyższym poziomie.

Oznacza to również, że ABI jest zoptymalizowana pod kątem SSE; oraz, że można wektoryzować obliczenia, gdy są dostępne, i że logika sterowania jest zoptymalizowana dla architektury.

btw. nawet FLD; FIST sekwencja nie powinna trwać dłużej niż ~ 7 cykli zegara na Pentium.

+3

Musisz zmienić tryb zaokrąglania, aby uzyskać poprawne obcięcie. Zmiana słowa statusu x87 jest powolna, o ile wiem. –

+0

@ komentarz infakty jest poprawny –

+0

Dobra uwaga. Byłoby zatem rozsądnie nie zmieniać słowa statusowego _often_. –

Powiązane problemy