Строгий fp в Java
Я внедряю некоторые библиотеки нейронной сети в Java, и там интенсивно double
(не Double
) матричные операции, матрицы большие и производительность, конечно, требуется.
Итак, я пришел, чтобы прочитать о strictfp
Ключевое слово, я честно не понимал, что именно оно делает, и я искал простое объяснение о том, должен ли я использовать его или нет, и почему
4 ответа
strictfp указывает, что для вычислений с плавающей запятой следует использовать точный стандарт IEEE754. Без strictfp виртуальная машина может свободно использовать другие (но зависящие от платформы) представления промежуточных значений с плавающей запятой и двойных значений, чтобы повысить точность.
Используйте strictfp, если вам нужны одинаковые результаты на разных платформах. Избегайте этого, если хотите добиться максимальной точности, которую может дать ваша текущая платформа.
Например, в следующем простом дополнении:
2.0 + 1.1 + 3.0
Вы хотите, чтобы промежуточные результаты (например, 2.0 + 1.1) были представлены в виде двойного стандарта IEEE754 или с максимально возможной точностью, которую позволяет ваша платформа. StrongFP обеспечивает первое, а не использование StrongFP позволяет виртуальной машине использовать второй вариант.
Если не использовать strictfp, это не повлияет на производительность и может на платформах, где собственные типы с плавающей запятой не отображаются в IEEE754, повысить производительность, поскольку виртуальная машина не требуется для преобразования между исходным форматом и форматом IEEE754. Ответ зависит от платформы, вам нужно измерить.
Существует стандарт IEEE о хранении числа с плавающей запятой. Этот стандарт хорошо работает на всех платформах, но имеет некоторые недостатки, например, с переполнением и понижением.
Некоторые платформы оптимизировали способ хранения чисел с плавающей запятой, так как в Java 1.2 JVM пытается использовать эти оптимизированные возможности. Проблема в том, что теперь недостатки могут отличаться от одной платформы к другой или даже полностью исчезать.
Таким образом, любой код, который полагался на эти недостатки, может не работать на некоторых платформах, strictfp
Ключевое слово было введено в качестве обходного пути. Когда вы используете это ключевое слово, Java будет использовать стандарт IEEE, что обеспечивает большую совместимость на всех платформах.
Однако, поскольку оптимизация платформы больше не используется, вычисления с плавающей запятой происходят медленнее. strictfp
,
Что касается производительности, вам не следует смешивать код с / без ключевого слова strictfp, поскольку это может привести к снижению производительности на 20–30% (проверено на JDK 1.7 для точных преобразований Фурье).
Что касается точности, то они одинаковы (более 1e-14 абсолютных или относительных погрешностей): это позволяет использовать только показатель большей степени, чтобы избежать переполнения или переполнения
Если вы хотите, чтобы другие исследователи обучали одну и ту же нейронную сеть, используя те же тренировочные данные и те же случайные начальные числа, независимо от их ЦП, используйте strictfp
, Воспроизводимость научных результатов (или точных битовых единичных тестов) является основным использованием для строгого фп. Для повседневного использования это наносит ущерб производительности и численной стабильности.