У меня есть значительная модель (~ 5000 строк), написанная на C. Это последовательная программа, нигде не генерирующая случайные числа. Она использует библиотеку FFTW для функций, использующих FFT - я не знаю деталей реализации FFTW, но я предполагаю, что функции в ней также являются детерминированными (поправьте меня, если я ошибаюсь).
Проблема, которую я не могу понять, заключается в том, что я получаю небольшие различия в результатах для идентичных прогонов на одной и той же машине (тот же компилятор, те же библиотеки).
Я использую переменные двойной точности, и для вывода результата в переменную, value
например, я выдаю:
fprintf(outFID, "%.15e\n", value);
или
fwrite(&value, 1, sizeof(double), outFID);
И я бы постоянно получал различия, такие как:
2.07843469652206 4 e-16 против 2.07843469652206 3 e-16
Я потратил много времени, пытаясь понять, почему это так. Сначала я думал, что один из моих чипов памяти испортился, и я заказал и заменил их, но безрезультатно. Впоследствии я также попытался запустить свой код на компьютере коллеги с Linux, и у меня возникли различия той же природы.
Что может быть причиной этого? Сейчас это небольшая проблема, но мне интересно, является ли это «верхушкой айсберга» (серьезной проблемы).
Я решил опубликовать здесь вместо StackOverflow, если кто-то, работающий с числовыми моделями, может столкнуться с этой проблемой. Если кто-то может пролить свет на это, я был бы очень благодарен.
Продолжение комментариев:
Кристиан Класон и Викрам: во-первых, спасибо за внимание к моему вопросу. Статьи, на которые вы ссылаетесь, предполагают, что: 1. ошибки округления ограничивают точность, и 2. другой код (например, введение, казалось бы, безвредных операторов печати) может повлиять на результаты вплоть до epsilon машины. Я должен уточнить, что я не сравниваю эффекты fwrite
и fprintf
функции. Я использую один или другой. В частности, один и тот же исполняемый файл используется для обоих запусков. Я просто заявляю, что проблема возникает, использую ли я fprintf
ИЛИ fwrite
.
Таким образом, путь к коду (и исполняемый файл) одинаков, а оборудование одинаково. Когда все эти внешние факторы остаются постоянными, откуда берется случайность? Я подозревал, что переворот произошел из-за того, что неисправная память не сохранила немного корректно, поэтому я заменил микросхемы памяти, но здесь это не проблема, я это проверил, и вы указали. Моя программа выводит тысячи этих чисел двойной точности за один прогон, и всегда есть случайная кучка, которая имеет случайные перевороты битов.
Продолжение № 2 :
Это график временных рядов, выводимых моделью, чтобы помочь в обсуждении ответвления в комментариях.