2013-05-14 19 views
6

Moim celem jest przeprowadzenie symulacji, która wymaga niecałkowitych liczb na różnych komputerach, które mogą mieć różne architektury i systemy procesorów. Głównym priorytetem jest to, że przy tym samym stanie początkowym, każda maszyna powinna odtworzyć symulację dokładnie tak samo. Drugorzędnym priorytetem jest to, że chciałbym, aby obliczenia miały wydajność i precyzję tak blisko, jak to tylko możliwe realistycznie, do pływaków z podwójną precyzją.Jaki jest najskuteczniejszy sposób na przeprowadzanie wieloplatformowych, deterministycznych symulacji w Haskell?

O ile mi wiadomo, nie wydaje się być jakiś sposób wpłynąć na determinizm pływających obliczenia punktów z programu Haskell, podobny do _controlfp i _FPU_SETCW makr w C. Tak więc, w tej chwili uważam moje opcje być

  1. Zastosowanie Data.Ratio
  2. Zastosowanie Data.Fixed
  3. Zastosowanie Data.Fixed.Binary z pakietu fixed-point
  4. Napisz moduł, aby zadzwonić pod numer _ controlfp (lub równoważny dla każdej platformy) przez FFI.
  5. Prawdopodobnie coś innego?

Jednym z problemów z bibliotekami arytmetycznymi ze stałymi punktami jest to, że nie mają one np. funkcje trygonometryczne lub logarytmy zdefiniowane dla nich (ponieważ nie implementują one klasy typu Floating), więc przypuszczam, że musiałbym zapewnić tabele odnośników dla wszystkich funkcji w danych początkowych symulacji. Czy jest jakiś lepszy sposób?

Oba bibliotekach punktów stałych ukryć również konstruktora newtype, więc każdy (de-) serializacji musiałyby być zrobione poprzez toRational/fromRational miarę mogę powiedzieć, i że czuje się jak byłoby dodawać niepotrzebnych napowietrznych.

Moim następnym krokiem jest porównanie różnych rozwiązań z ustalonym punktem widzenia, aby zobaczyć rzeczywisty występ, ale tymczasem chętnie skorzystam z wszelkich porad na ten temat.

+0

Jak różnorodne mogą być platformy?Na wszystko rozsądne, powinieneś być w porządku z 'Double', używając' -msse2' na platformach 32-bitowych (domyślnie w wersji 64-bitowej). –

+0

Daniel Fischer: Nie muszę wspierać żadnych platform ezoterycznych, ale różnych (nowoczesnych) smaków Windows, Linux i MacOSX zarówno w wersji 32-bitowej, jak i 64-bitowej. Czytanie [tej strony] (http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/) pozostawiło mnie w przekonaniu, że samo poleganie na instrukcjach sse2 może nie być wystarczające w realnym świecie (tm) i że używanie arytmetyki stałoprzecinkowej może być o wiele mniej bolesne. – shang

Odpowiedz

7

W klauzuli 11 normy IEEE 754-2008 opisano, co jest potrzebne dla odtwarzalnych wyników zmiennoprzecinkowych. Między innymi potrzebujesz jednoznacznych reguł oceny ekspresji. Niektóre języki pozwalają na interpretowanie wyrażeń zmiennoprzecinkowych z dodatkową precyzją lub dopuszczają pewne zmiany wyrażeń (np. Ocenianie a*b+c w pojedynczej instrukcji zamiast oddzielnego mnożenia i dodawania instrukcji). Nie wiem o semantyce Haskella. Jeśli Haskell nie mapuje dokładnie wyrażeń na określone operacje zmiennoprzecinkowe, wówczas nie może obsługiwać odtwarzalnych wyników zmiennoprzecinkowych.

Ponadto, ponieważ wspomniane są funkcje trygonometryczne i logarytmiczne, należy pamiętać, że różnią się one od wdrożenia do wdrożenia. Nie znam żadnej biblioteki matematycznej, która zapewnia poprawnie zaokrąglone implementacje każdej standardowej funkcji matematycznej. (CRLibm to projekt do stworzenia.) Tak więc każda biblioteka matematyczna wykorzystuje własne przybliżenia, a ich wyniki różnią się nieznacznie. Być może możesz obejść to, włączając bibliotekę matematyczną z kodem symulacji, tak aby była używana zamiast każdej domyślnej biblioteki implementacji Haskella.

Procedury konwertujące binarne liczby zmiennoprzecinkowe i dziesiętne są również źródłem różnic między implementacjami. Jest to mniejszy problem niż kiedyś, ponieważ znane są algorytmy do konwersji. Jednak jest to coś, co może wymagać sprawdzenia w każdej implementacji.

Powiązane problemy