Mam spory model (~ 5000 linii) napisany w C. Jest to program szeregowy, bez generowania liczb losowych w dowolnym miejscu. Wykorzystuje bibliotekę FFTW dla funkcji korzystających z FFT - nie znam szczegółów implementacji FFTW, ale zakładam, że funkcje w niej również są deterministyczne (poprawcie mnie, jeśli się mylę).
Problem, którego nie rozumiem, polega na tym, że otrzymuję małe różnice w wynikach dla identycznych uruchomień na tym samym komputerze (ten sam kompilator, te same biblioteki).
Używam zmiennych o podwójnej precyzji i na przykład w wyniku wypisuję zmienną value
:
fprintf(outFID, "%.15e\n", value);
lub
fwrite(&value, 1, sizeof(double), outFID);
I ciągle otrzymywałbym różnice, takie jak:
2.07843469652206 4 e-16 vs. 2.07843469652206 3 e-16
Spędziłem dużo czasu próbując zrozumieć, dlaczego tak jest. Początkowo myślałem, że jeden z moich układów pamięci zepsuł się i zamówiłem je i wymieniłem, ale bezskutecznie. Następnie spróbowałem uruchomić mój kod na maszynie Linuksa kolegi i dostaję różnice o tym samym charakterze.
Co może być tego przyczyną? Jest to teraz niewielka kwestia, ale zastanawiam się, czy jest to „wierzchołek góry lodowej” (poważny problem).
Myślałem, że opublikuję tutaj zamiast StackOverflow na wypadek, gdyby ktoś pracujący z modelami numerycznymi napotkał ten problem. Gdyby ktoś mógł rzucić na to światło, byłbym bardzo zobowiązany.
Kontynuacja komentarzy:
Christian Clason i Vikram: po pierwsze, dziękuję za uwagę na moje pytanie. Artykuły, które podłączyłeś, sugerują, że: 1. błędy zaokrąglania ograniczają dokładność, oraz 2. inny kod (np. Wprowadzanie pozornie nieszkodliwych instrukcji drukowania) może wpływać na wyniki aż do epsilon maszyny. Powinienem wyjaśnić, że nie porównuję efektów fwrite
i fprintf
funkcji. Używam jednego LUB drugiego. W szczególności ten sam plik wykonywalny jest używany dla obu przebiegów. Po prostu stwierdzam, że problem występuje bez względu na to, czy używam fprintf
OR fwrite
.
Zatem ścieżka do kodu (i wykonywalna) jest taka sama, a sprzęt jest taki sam. Przy tych wszystkich czynnikach zewnętrznych utrzymywanych na stałym poziomie, skąd zasadniczo bierze się przypadkowość? Podejrzewałem, że bit się odwrócił, ponieważ uszkodzona pamięć nie zachowuje się trochę poprawnie, dlatego wymieniłem układy pamięci, ale to nie wydaje się być problemem tutaj, zweryfikowałem i wskazałeś. Mój program generuje tysiące tych podwójnie precyzyjnych liczb w jednym przebiegu i zawsze istnieje losowa garść, która ma losowe odwrócenie bitów.
Kontynuacja pierwszego komentarza Christiana Clasona: Dlaczego tym samym co 0 w zakresie precyzji maszyny? Najmniejsza liczba dodatnia dla podwójnego to 2.22e-308, więc czy nie powinno to być równe 0? Mój program generuje tysiące wartości w zakresie 10 ^ -16 (od 1e-15 do 8e-17) i widzieliśmy znaczące różnice w naszym projekcie badawczym, więc mam nadzieję, że nie patrzyliśmy na nonsensowne liczby.
Kontynuacja # 2 :
Jest to wykres szeregów czasowych generowanych przez model, aby pomóc w dyskusji na temat odejścia w komentarzach.