gcc -Ofast - полный список ограничений
Я использую -Ofast
Опция gcc в моей программе вызывает требования к задержке. Я написал простую тестовую программу:
#include <iostream>
#include <math.h>
static double quiet_NaN = std::numeric_limits<double>::quiet_NaN();
int main()
{
double newValue = 130000;
double curValue = quiet_NaN;
printf("newValue = %f\n", newValue);
printf("curValue = %f\n", curValue);
printf("isnan(newValue) = %d\n", isnan(newValue));
printf("isnan(curValue) = %d\n", isnan(curValue));
printf("newValue == curValue %d\n", (newValue == curValue));
printf("newValue != curValue %d\n", (newValue != curValue));
}
Я попытался запустить его с флагами по умолчанию и с -Ofast:
$ g++ TestPointer.cpp
$./a.out
newValue = 130000.000000
curValue = nan
isnan(newValue) = 0
isnan(curValue) = 1
newValue == curValue 0
newValue != curValue 1
$ g++ -Ofast TestPointer.cpp
$ ./a.out
newValue = 130000.000000
curValue = nan
isnan(newValue) = 0
isnan(curValue) = 1
newValue == curValue 1
newValue != curValue 0
Итак, результат !=
а также ==
нельзя доверять. Значит ли это, что я должен ==
а также !=
только когда известно, что оба значения не являются nan, иначе я должен проверить с isnan
до?
Гарантируется ли это, что isnan
правильно работает с -Ofast
? Как правильно ==
а также !=
работает на двоих с -Ofast
? Может ли кто-нибудь предоставить полный список ограничений, добавленных -Ofast
?
1 ответ
Вы наблюдаете за эффектами -ffast-math
,
Из документов:
-Ofast
Игнорировать строгое соответствие стандартам. -Ofast включает все оптимизации -O3. Он также позволяет выполнять оптимизацию, которая не подходит для всех стандартных программ. Он включает -ffast-math и специфичные для Fortran -fno-protect-parens и -fstack-arrays.
а также
-ffast-математический
Устанавливает -fno-math-errno, -funsafe-math-optimizations, -fno-trapping-math, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans и fcx-limited-range.
а также
-ffinite-математических только
Разрешить оптимизацию для арифметики с плавающей точкой, которая предполагает, что аргументы и результаты не являются NaN или + -Infs.
Существует несколько отчетов об ошибках gcc для этого помеченного как недействительного.
Кроме того, сравнение строгих плавающих точек IEEE всегда приводит к ложному.
Проверка, является ли double (или float) NaN в C++
Это не обязательно относится к -ffast-math
но это объясняет, что вы показываете.
GCC не описывает формальный стандарт для того, как -ffast-math
float работает, так что вам просто нужно проработать детали эмпирически, если вы должны, а не предполагать согласованность между версиями gcc. Еще лучше, полностью избежать комбинации NaN
а также -ffast-math
,