Powiedziano mi, że większość współczesnych komputerów stosuje ten sam standard zmiennoprzecinkowy. Czy to oznacza, że wszystkie otrzymają tę samą odpowiedź zmiennoprzecinkową dla danej operacji matematycznej, jeśli dane wejściowe są takie same?
Pytam, ponieważ pracuję nad stworzeniem gry RTS w sieci, a zsynchronizowanie setek pozycji jednostek wydaje się kiepską drogą.
Więc jeśli przesyłam tylko dane wejściowe, muszę zagwarantować, że wszyscy klienci uzyskają ten sam wynik, uruchamiając symulację z tych danych wejściowych.
Czytałem, że starsze gry RTS używały arytmetyki stałoprzecinkowej, ale nie wiem, czy jest to nadal wymagane na nowoczesnych komputerach, jeśli wszystkie są zgodne z tym samym standardem? Powiedziano mi również, że chociaż nieprecyzyjny, wynik zmiennoprzecinkowy jest deterministyczny dla tego samego wejścia (co zakładam, że każdy komputer zgodny z tym samym standardem otrzymuje ten sam niedokładny wynik?).
Czy komputery nadal mają odchylenia, nawet jeśli są zgodne z tym samym standardem liczb zmiennoprzecinkowych?
Piszę tę grę w C #, nie jestem pewien, czy to ma znaczenie, pomyślałem, że i tak o tym wspomnę.
źródło
Odpowiedzi:
Niestety tak, szczególnie gdy używasz C # (lub innego skompilowanego języka JIT). Problem, który występuje tutaj, polega na tym, że etap kompilacji JIT na niektórych architekturach procesorów wytwarza kod, który wykorzystuje więcej rejestrów procesora niż na innych architekturach. Może to prowadzić do sytuacji, w których na niektórych komputerach do niektórych operacji używana jest rozszerzona precyzja zmiennoprzecinkowa , podczas gdy na innych nie. Oznacza to, że dla każdego iteracyjnego obliczenia przy użyciu podwójnych istnieje szansa na wygenerowanie różnych skumulowanych błędów zaokrąglania.
To nie jest hipotetyczny problem, mam doświadczenie z pierwszej ręki z takimi odchyleniami we współczesnym oprogramowaniu do symulacji inżynieryjnych na mniej lub bardziej nowoczesnym sprzęcie. Ten problem naprawdę utrudnia stworzenie wiarygodnych testów regresji dla złożonych obliczeń zmiennoprzecinkowych, które dają dokładnie taki sam wynik na wszystkich zaangażowanych maszynach.
źródło
FLT_EVAL_METHOD
W ISO C / C ++. Funkcje transcendentalne (npsin
,exp
,log
) są w znacznym stopniu nieuregulowany zarówno ze standardem IEEE zmiennoprzecinkowych oraz programowania norm językowych. Prosta aktualizacja wersji biblioteki (np. Nowaglibc
wersja) może powodować różnice w wynikach.Błędy zmiennoprzecinkowe
Każda liczba zmiennoprzecinkowa kumuluje niedokładność, ponieważ jest używana do obliczeń. Jest to prosty fakt użycia nieprecyzyjnego formatu do obliczenia. Obliczenia są również wrażliwe na kolejność obliczeń, przemienność nie jest gwarantowana, tzn .:
(a + b) + c
może być taka sama, jaka + (b + c)
.Dodatkowo procesory niekoniecznie mają taką samą długość mantysy jak standard pamięci. Może to generować interesujące zachowanie, ponieważ zmiennoprzecinkowe 32/64/128 bitów czasami działają tak, jakby miały więcej bitów.
Błędy o stałym punkcie
Biorąc to pod uwagę, arytmetyka stałoprzecinkowa może również kumulować błędy. Różnica polega na tym, że liczby punktów stałych są jasne na temat utraty precyzji, a w zależności od wybranych operacji mogą całkowicie uniknąć błędów zaokrąglania. Są również przemienne
(a + b) + c = a + (b + c)
.Który?
To, którego użyć, zależy całkowicie od potrzebnych właściwości.
Liczb zmiennoprzecinkowych:
Numery stałych punktów:
źródło
(a + b * c) / d - e
. Z wyjątkiem oczywistych problemów, takich jakNaN
dzielenie przez zero lub przepełnienie / niedopełnienie, to wyrażenie może być niepoprawne. Dodaj do tego impedancja między pamięcią a rejestrem pod względem precyzji, a nawet zwykłe ładowanie / przechowywanie z pamięci „tej samej” wartości zmiennoprzecinkowej zmieni odpowiedź.Istnieje pytanie, dlaczego chcesz zagwarantować identyczne wyniki, ponieważ identyczne wyniki nie dają żadnej gwarancji, że Twoje wyniki są przydatne .
Możesz mieć algorytm niestabilny numerycznie, który daje dwa identyczne, ale całkowicie bezsensowne wyniki na różnych komputerach. Jeśli istnieją różnice, ale wyniki są takie same w obrębie 13 cyfr, jest to o wiele bardziej wiarygodne.
Jest bardzo niewiele sytuacji, w których odtwarzalność jest naprawdę ważna: w silniku układu lub bezstratna kompresja / dekompresja. Korzystanie z punktu stałego jest bardzo mylne.
źródło