Czy nadal muszę używać stałego punktu, aby zagwarantować, że komputery uzyskają taki sam wynik w przypadku operacji matematycznych?

9

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ę.

WDUK
źródło
Nawet gdyby tak zrobili, nie
użyłbym
Co masz na myśli ? Dlaczego nie?
WDUK,
Korzystanie z pływaków i tak może być niepożądane, ponieważ zachowanie może zależeć od pozycji na mapie. Dalekie ziemie Minecrafta były bardziej godnym uwagi przykładem: ruch, renderowanie i generowanie terenu stawałyby się błędne, gdy odsuwałeś się daleko od miejsca odrodzenia.
amon

Odpowiedzi:

18

Czy komputery nadal mają odchylenia, nawet jeśli są zgodne z tym samym standardem liczb zmiennoprzecinkowych?

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.

Doktor Brown
źródło
To. Niektóre podstawowe przyczyny: IEEE Std 754 zawiera opcjonalne klauzule „należy” (np. Obsługa NaN) i pozwala na alternatywne rozwiązania projektowe (np. Wykrywanie niedomiaru). O ile powiązania językowe obsługują standard zmiennoprzecinkowy, mogą nadal dawać swobodę kompilatorowi podczas oceny wyrażeń zmiennoprzecinkowych, np. FLT_EVAL_METHODW ISO C / C ++. Funkcje transcendentalne (np sin, exp, log) są w znacznym stopniu nieuregulowany zarówno ze standardem IEEE zmiennoprzecinkowych oraz programowania norm językowych. Prosta aktualizacja wersji biblioteki (np. Nowa glibcwersja) może powodować różnice w wynikach.
njuffa,
Uderzyłem to sam w grę. Rakieta leciała dobrze na moim laptopie, nie latała na pulpicie, całkowicie identyczne instalacje.
Loren Pechtel,
3

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) + cmoże być taka sama, jak a + (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:

  • dają szeroki zakres wartości, które stają się bardzo drobnoziarniste z bliska i stopniowo oddalają się w skrajności.
  • są wrażliwe na kolejność obliczeń
  • gromadzą błędy zaokrąglania w czasie.
  • może mieć nieprawidłowe działanie z powodu niedopasowania rozmiaru pływaka pamięci / sprzętu.

Numery stałych punktów:

  • podać mniejszy zakres liczb z jednakową odległością między dowolnymi dwoma kolejnymi liczbami.
  • są mniej wrażliwe na kolejność obliczeń
  • są jaśniejsze o błędach zaokrąglania
  • można pracować, aby zminimalizować / uniknąć problemów z zaokrąglaniem.
Kain0_0
źródło
1
„liczby punktów stałych są jasne na temat utraty precyzji” - punkty zmienne są również jasne, różnica polega raczej na tym, że niedokładności punktów stałych są bardziej intuicyjne w stosunku do zwykłej numeracji życia
whatsisis
1
Czy tylko punkt stały gwarantuje, że na wszystkich komputerach, niezależnie od sprzętu itp., Wystąpią te same błędy / utrata precyzji?
WDUK,
1
Zasadniczo tak, ponieważ można określić, że numery stałych punktów mają 32 lub 64 bity i będą dostępne we wszystkich systemach. Liczby zmiennoprzecinkowe mogą być 32- lub 64-bitowe, ale sprzęt może faktycznie użyć 48 lub 96 bitów do wykonania obliczeń i konwersji na 32 lub 64 bity na końcu, co powoduje różnice między różnymi typami sprzętu.
user1118321,
@whatsisname Chociaż pływających specyfikacje punktowe są całkiem jasne, nie można łatwo mi powiedzieć, jakie problemy napotykają zaokrąglania będę w tej sumy: (a + b * c) / d - e. Z wyjątkiem oczywistych problemów, takich jak NaNdzielenie 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ź.
Kain0_0,
@ Kain0_0: masz rację, nie mogę z łatwością powiedzieć ci, co napotkam, ponieważ nie jestem ekspertem od liczb zmiennoprzecinkowych. Właśnie to ma na myśli, gdy powiedziałem „bardziej intuicyjnie w stosunku do zwykłej numeracji życia”. Kiedy mówisz, że ustalony punkt jest „czysty”, a zmiennoprzecinkowy nie, brzmi to tak, jakby liczby zmiennoprzecinkowe były po prostu przypadkowo niedokładne.
whatsisname
-1

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.

gnasher729
źródło
Nie głosowałem za twoją odpowiedzią, ale wydaje się, że przypadek opisany przez PO jest dokładnie „jedną z niewielu sytuacji, w których odtwarzalność jest naprawdę ważna”. W grze RTS niewielki błąd zaokrąglenia może spowodować różnicę między „zderzeniem dwóch obiektów” lub nie.
Doc Brown,