Мне сказали, что большинство современных компьютеров следуют одному и тому же стандарту с плавающей запятой, означает ли это, что все они получат один и тот же ответ с плавающей запятой для данной математической операции, если входные данные одинаковы?
Я спрашиваю, потому что я исследую создание игры RTS в сети, и синхронизация сотен позиций юнитов звучит как плохой путь.
Поэтому, если я отправляю только входные данные, мне нужно гарантировать, что все клиенты получат одинаковый результат, если они запустят симуляцию с этих входных данных.
Я читал, что в старых играх RTS использовалась арифметика с фиксированной запятой, но я не знаю, требуется ли это на современных компьютерах, если они все придерживаются одного и того же стандарта? Мне также сказали, что, хотя неточный, результат с плавающей запятой является детерминированным для одного и того же ввода (что, я предполагаю, означает, что любой компьютер, следующий тому же стандарту, получает тот же неточный результат?).
Есть ли у компьютеров отклонения, даже если они следуют одному и тому же стандарту с плавающей запятой?
Я пишу эту игру на C #, но не уверен, что это имеет значение, но я все равно упомяну об этом.
источник
Ответы:
К сожалению, да, особенно когда вы используете C # (или другой язык, скомпилированный JIT). Проблема, которая возникает здесь, состоит в том, что этап компиляции JIT на некоторых процессорных архитектурах создает код, который использует больше регистров процессора, чем на других архитектурах. Это может привести к ситуациям, когда на некоторых машинах для определенных операций используется расширенная точность с плавающей запятой , а на других - нет. Это означает, что для каждого итеративного вычисления, использующего двойные значения, существует вероятность получения различных накопленных ошибок округления.
Это не гипотетическая проблема, у меня есть опыт из первых рук с такими отклонениями в современном программном обеспечении для инженерного моделирования, на более или менее современном оборудовании. Эта проблема действительно затрудняет создание надежных регрессионных тестов для сложных вычислений с плавающей запятой, которые дают одинаковый результат на всех задействованных машинах.
источник
FLT_EVAL_METHOD
в ISO C / C ++. Трансцендентные функции (напримерsin
,exp
,log
) в значительной степени нерегулируемых оба стандарта с плавающей точкой IEEE и программированием стандартов языка. Простое обновление версии библиотеки (например, новаяglibc
версия) может привести к отличиям результатов.Ошибки с плавающей точкой
Каждое число с плавающей запятой накапливает неточность, поскольку оно используется для расчета. Это простой факт использования неточного формата для расчета в. Расчеты также чувствительны к порядку расчета, коммутативность не гарантируется, т.
(a + b) + c
Е. Может совпадать или не совпадать сa + (b + c)
.Кроме того, процессоры не обязательно имеют ту же длину мантиссы, что и стандарт памяти. Это может привести к интересному поведению, так как 32/64/128-битное значение с плавающей запятой иногда работает так, как будто у них больше битов.
Ошибки с фиксированной точкой
При этом арифметика с фиксированной точкой также может накапливать ошибки. Разница в том, что числа с фиксированной запятой ясны в отношении того, какая точность потеряна, и в зависимости от выбранных операций можно полностью избежать ошибок округления. Они также коммутативны
(a + b) + c = a + (b + c)
.Который?
Какой из них использовать, полностью зависит от того, какие свойства вам нужны.
Числа с плавающей точкой:
Номера с фиксированной точкой:
источник
(a + b * c) / d - e
. За исключением очевидных проблем, таких какNaN
деление на ноль или переполнение / недополнение, возможно, что это выражение будет неправильным. Добавьте к этому зависимость между памятью и регистром с точки зрения точности, и даже простая загрузка / сохранение из памяти «того же» значения с плавающей запятой изменит ответ.Возникает вопрос, почему вы хотите гарантировать одинаковые результаты, поскольку идентичные результаты не дают никакой гарантии того, что ваши результаты полезны .
У вас может быть численно нестабильный алгоритм, который дает два одинаковых, но совершенно бессмысленных результата на разных компьютерах. Если есть различия, но результаты совпадают в пределах 13 цифр, это гораздо более достоверно.
Очень мало ситуаций, в которых воспроизводимость действительно важна: в механизме компоновки или сжатии / декомпрессии без потерь. Использование фиксированной точки, скорее всего, будет ошибочным.
источник