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 для этого помеченного как недействительного.

Проблемы с -fast-math и isnan

Кроме того, сравнение строгих плавающих точек IEEE всегда приводит к ложному.

Проверка, является ли double (или float) NaN в C++

Это не обязательно относится к -ffast-math но это объясняет, что вы показываете.

GCC не описывает формальный стандарт для того, как -ffast-math float работает, так что вам просто нужно проработать детали эмпирически, если вы должны, а не предполагать согласованность между версиями gcc. Еще лучше, полностью избежать комбинации NaN а также -ffast-math,

Другие вопросы по тегам