2011-01-03 9 views
34

Czytam "przyspieszone C++". Znalazłem jedno zdanie, które stwierdza "czasami double jest szybsze w wykonaniu niż float w C++". Po przeczytaniu zdania wpadłem w zakłopotanie z powodu pracy float i double. Proszę wyjaśnij mi ten punkt.double lub float, który jest szybszy?

+6

Niemal taka sama jak: http://stackoverflow.com/questions/417568/float-vs-double-performance –

+0

@Devendra: To C#, nie C++. – AbdullahC

+4

Jeśli czytasz "przyspieszone C++", ostatnią rzeczą, o którą powinieneś się martwić, jest to, który typ jest szybszy - skup się na koncepcjach i kiedy masz prawdziwy problem, a następnie martw się o to ... – Nim

Odpowiedz

38

Zależy od tego, co robi sprzęt natywny.

  • Jeśli komputer realizuje podwójna (jak x86 nie), po czym pływak jest emulowanym rozszerzając go tam i konwersja Koszt czasu. W takim przypadku podwójne będzie szybsze.

  • Jeśli narzędzia sprzętowe unosić tylko wtedy emulacji dwukrotnie z nim będzie kosztować jeszcze więcej czasu. W takim przypadku float będzie szybszy.

  • A jeśli sprzęt nie realizuje, i oba muszą być wdrożone w oprogramowaniu. W tym przypadku oba będą powolne, ale podwójne będą nieco wolniejsze (więcej operacji ładowania i przechowywania co najmniej).

Cytat wspomnieć zapewne powołując się na platformie x86, gdzie pierwszy przypadek był podane. Ale to ogólnie nie jest prawdą.

+18

AFAIK x86 ma w rzeczywistości rejestry 80-bitowe, nie pływające ani podwójne. – ybungalobill

+0

Dodatkowo zależy to od ilości przetwarzanych danych. Przy dużych macierzach lub tablicach pamięć podręczna może zacząć wpływać na wydajność. –

+0

@Bart, testowałem już wcześniej i zasadniczo podwójnie zmierzam do wygrania z floatem, nawet z dużymi zestawami danych. Jeśli chcesz mieć pewność, że powinieneś zrobić benchmark, ale w zasadzie float rzadko wygrywa na x86. –

23

można znaleźć pełną odpowiedź na temat tego artykułu

What Every Computer Scientist Should Know About Floating-Point Arithmetic

To jest cytat z poprzedniego wątku przepełnienie stosu float x podwójne dotyczące Przepustowość pamięci

Jeśli podwójna wymaga więcej pamięci niż zmiennoprzecinkowej, następnie odczytanie danych zajmie więcej czasu. To naiwna odpowiedź. W przypadku nowoczesnego modelu IA32 wszystko zależy od tego skąd pochodzą dane. Jeśli jest w pamięci podręcznej L1, , obciążenie jest pomijalne, pod warunkiem, że dane pochodzą z pojedynczej linii pamięci podręcznej. Jeśli obejmuje więcej niż jedną linię pamięci podręcznej , istnieje niewielki narzut. Jeśli jest to od L2, trwa to trochę dłużej, jeśli jest to w pamięci RAM, to jest dłuższe i wreszcie, jeśli jest na dysku, to jest to wielki czas . Tak więc wybór wartości zmiennoprzecinkowej lub podwójnej jest mniej istotny niż sposób, w jaki używane są dane . Jeśli chcesz wykonać małe obliczenia dla wielu sekwencyjnych danych , preferowany jest mały typ danych. Wykonanie wielu obliczeń na małym zestawie danych pozwoliłoby na użycie większych typów danych o z dowolnym znaczącym efektem . Jeśli bardzo losowo uzyskujesz dostęp do danych , rozmiar danych o rozmiarze jest nieistotny - dane są ładowane w wierszach stron/pamięci podręcznej. Więc nawet jeśli chcesz tylko bajt z pamięci RAM, możesz przenieść 32 bajty przeniesione (jest to bardzo zależne od architektury systemu ). Co więcej, procesor/jednostka FPGA może być super-skalarna (określana również jako ). Tak więc, chociaż obciążenie może potrwać kilka cykli, CPU/FPU mogło być zajęty robi coś innego (a mnożyć na przykład), który ukrywa czas obciążenia w stopniu

+0

+1 za link do artykułu :-) – Nawaz

+0

+1 ode mnie oraz za ten link. – foo

3

mogę myśleć o dwóch podstawowe przypadki podwaja się szybciej niż pływaków:

  1. Twój sprzęt obsługuje podwójne operacje ale nie unoszą się operacji, więc pływaki będą emulowane programowo, a zatem wolniej.

  2. Naprawdę potrzebujesz precyzji podwójnej. Teraz, jeśli używasz pływaków i tak będziesz musiał użyć dwóch pływaków, aby osiągnąć podobną dokładność do podwojenia. Emulacja prawdziwego double'a z float będzie wolniejsza niż użycie float w pierwszej kolejności.

    1. Nie potrzebujesz podwajać, ale twój algorytm numeryczny zbiegnie się szybciej dzięki zwiększonej precyzji podwójnej liczby. Podwójne może również zapewnić wystarczającą precyzję, aby w ogóle użyć szybszego, ale mniej stabilnego algorytmu liczbowego.

Dla kompletności boską ja również podać kilka powodów przeciwnym przypadku pływaki są szybciej. Można zobaczyć na własne oczy whichs powody dominować w Twoim przypadku:

  1. pływaków są szybsze niż podwaja gdy nie trzeba podwójnego na precyzję i jesteś przepustowość pamięci związany i sprzęt nie niesie karę na pływakach.

  2. Oszczędzają one przepustowość pamięci, ponieważ zajmują połowę miejsca na numer .

  3. Istnieją również platformy, które mogą przetwarzać więcej jednostek pływających niż podwajają się razem .

+0

Ponieważ wielokrotnie dostaję odkomentowane pomyłki, postanowiłem zmienić moją odpowiedź. Nowe rzeczy znajdują się w pierwszej części odpowiedzi. –

1

Pływak jest zwykle szybszy. podwójne zapewnia większą precyzję. Jednak wydajność może się różnić w niektórych przypadkach, jeśli używane są specjalne rozszerzenia procesorów, takie jak 3dNow lub SSE.

3

Intel, koprocesor (obecnie zintegrowany) będzie obsługiwać zarówno równie szybko, ale jak inni zauważyli, podwaja wynik w wyższej przepustowości pamięci, które mogą powodować zatory. Jeśli używasz skalarnych instrukcji SSE (domyślnie dla większości kompilatorów w 64-bitach), to samo dotyczy. Zasadniczo, jeśli nie pracujesz nad dużym zbiorem danych, nie ma to większego znaczenia.

Jednak instrukcje równoległe SSE pozwolą na obsługę czterech pływaków za pomocą jednej instrukcji, ale tylko dwóch podwójnych, dzięki czemu tutaj pływak może być znacznie szybszy.

8

Krótka odpowiedź brzmi: to zależy .

CPU z x87 będzie schrupać pływaków i podwaja się równie szybko. Wektoryzowany kod będzie działał szybciej w przypadku spławik, ponieważ SSE może zestrzelić 4 pływaki lub 2 podwójne w jednym przejściu.

Kolejną rzeczą do rozważenia jest szybkość pamięci. W zależności od algorytmu procesor może dużo pracować na biegu jałowym podczas oczekiwania na dane. Kod intensywnie wykorzystujący pamięć będzie korzystał z używania pływaków, ale ograniczony kod ALU nie będzie (chyba że jest wektoryzowany).

2

Jest tylko jeden powód, dla którego 32-bitowe pływaki mogą być wolniejsze niż 64-bitowe podwójne (lub 80-bitowe 80x87). I to jest wyrównanie. Poza tym, pływaki zajmują mniej pamięci, co ogólnie oznacza szybszy dostęp, lepszą wydajność pamięci podręcznej. Proces przetwarzania 32-bitowych instrukcji zajmuje również mniej cykli. Nawet jeśli (co) -procesor nie ma instrukcji 32-bitowych, może je wykonywać na 64-bitowych rejestrach z tą samą prędkością. Prawdopodobnie możliwe jest utworzenie przypadku testowego, w którym liczba podwójna będzie większa niż liczba zmiennoprzecinkowa i v.v., ale moje pomiary rzeczywistych statystyk algos nie wykazały zauważalnej różnicy.

+0

Wydaje się, że zakładasz, że dostęp do pamięci nie będzie kosztować żadnego czasu, ale z mojego doświadczenia (i arkuszy danych całego sprzętu, który widziałem), to znaczy, – foo

2

W eksperymentach dodając 3,3 do 2 miliardów razy, wyniki są następujące:

Summation time in s: 2.82 summed value: 6.71089e+07 // float 
Summation time in s: 2.78585 summed value: 6.6e+09 // double 
Summation time in s: 2.76812 summed value: 6.6e+09 // long double 

Więc podwoić jest szybsza i domyślne w C i C++. Jest bardziej przenośny i domyślny we wszystkich funkcjach biblioteki C i C++. Alos double ma znacznie wyższą precyzję niż float.

Nawet Stroustrup zaleca podwójna nad pływakiem.

„Dokładne znaczenie jedno-, dwu- i rozszerzonej precyzji jest realizacja zdefiniowane Wybór odpowiedniej precyzji dla problemu jeżeli materiał wybór wymaga znacznego zrozumienia Obliczenia zmiennoprzecinkowe: jeśli nie masz takiego zrozumienia, zasięgnij porady, poświęć czas na naukę lub użyj podwójnie i miej nadzieję na najlepsze.

Być może jedynym przypadkiem, w którym powinieneś używać float zamiast double, jest 64-bitowy sprzęt z nowoczesnym gcc. Ponieważ pływak jest mniejszy; double to 8 bajtów, a float 4 bajty.

+1

cóż, miejmy nadzieję, że to, co najlepsze, to –

+0

Double ma wyższą dokładność, która unosi się i używa więcej pamięci podwójne 8 bajtów i 4 bajty float Najszybsza jest przepuszczana przez pamięć, nie wiem jak wygląda twój test, ale czas jest głośny. –

Powiązane problemy