답변:
언급했듯이 엄격한 IEEE 준수를 유지하지 않는 최적화가 가능합니다.
예를 들면 다음과 같습니다.
x = x*x*x*x*x*x*x*x;
에
x *= x;
x *= x;
x *= x;
부동 소수점 산술은 연관성이 없으므로 연산의 순서 및 인수 분해는 반올림으로 인한 결과에 영향을줍니다. 따라서이 최적화는 엄격한 FP 동작에서 수행되지 않습니다.
실제로 GCC가 실제로이 특정 최적화를 수행하는지 확인하지 않았습니다. 그러나 아이디어는 동일합니다.
double
정도이지만 응용 프로그램에 따라 다름). 주목할 점은 ffast-math 최적화가 반드시 "더 많은"반올림을 추가 할 필요는 없다는 것입니다. IEEE와 호환되지 않는 유일한 이유는 답변이 작성된 것과 다르기 때문입니다.
x
10보다 작은 경우 Mystical의 예에서 오류는 약 10 ^ -10입니다. 그러나 그렇다면 x = 10e20
오류는 수백만이 될 것입니다.
-fassociative-math
어떤에 포함되어 -funsafe-math-optimizations
있는 다시 활성화됩니다 -ffast-math
하지 않습니다 GCC 최적화 왜 a*a*a*a*a*a
에 (a*a*a)*(a*a*a)
?
-ffast-math
엄격한 IEEE 준수를 깨뜨리는 것 이상을 수행합니다.
우선, 물론 깨집니다 엄격한 IEEE 준수를 , 예를 들어 부동 소수점에서 수학적으로 동일하지만 (이상적으로) 동일하지 않은 것으로 명령을 재정렬 할 수 있습니다.
둘째, 단일 명령어 수학 함수 후에 설정 을 비활성화 합니다 errno
. 이는 스레드 로컬 변수에 대한 쓰기를 피함을 의미합니다 (일부 아키텍처에서 해당 함수에 대해 100 % 차이를 만들 수 있음).
셋째, 모든 수학이 유한 한 것으로 가정합니다. 즉 , 해로운 영향을 미칠 수있는 NaN (또는 0) 검사가 수행되지 않습니다. 이것은 일어나지 않을 것이라고 간단히 가정합니다.
넷째, 나누기와 역 제곱근에 대한 역 근사 를 가능하게 합니다.
또한 부호있는 0 (목표가 지원하더라도 부호있는 0이 존재하지 않는다고 가정) 및 반올림 수학을 비활성화하여 컴파일 타임에 일정하게 접을 수 있습니다.
마지막으로,이 더 하드웨어 인터럽트 때문에 수학을 트래핑 / 신호 일어날 수 있다고 가정 코드 생성 (이 결과적으로 목표 아키텍처에서 사용할 수 있고 할 수없는 경우입니다 일어나지 않는을 , 그들은 처리되지 않습니다).
-ffast-math
설정 -fno-수학 errno를, -funsafe - 수학 - 최적화, -ffinite - 수학 만, -fno-반올림 - 수학, -fno-신호 -nans 및 -fcx-limited-range.이 옵션을 사용하면 전 처리기 매크로 FAST_MATH 가 정의됩니다. "및 ( math.h
math_errhandling 근처에서) 와 같은 glibc의 항목 " 기본적으로 모든 함수는 errno 및 예외 처리를 모두 지원합니다. gcc의 빠른 연산 모드 및 인라인 함수가 정의 된 경우 이는 사실이 아닐 수 있습니다. "
-ffast-math
컴파일러는 모서리를 자르고 약속을 어길 수 있습니다 (설명대로). 일반적으로 위험하지 않으며 대부분의 사람들에게 문제가되지 않습니다. 대부분의 사람들은 동일하고 더 빠릅니다. 그러나 코드 가 이러한 약속을 가정하고 의존하는 경우 코드가 예상과 다르게 동작 할 수 있습니다. 일반적으로 이는 프로그램이 대부분 제대로 작동하는 것처럼 보이지만 일부 결과는 "예상치 못한"결과를 가져올 수 있습니다 (예 : 물리 시뮬레이션에서는 두 객체가 제대로 충돌하지 않을 수 있음).
-O2
일반적으로 속도에 맞게 거래하는 것을 제외하고는 "모든"법적 최적화가 가능합니다. -O3
또한 속도를 위해 크기를 최적화하는 최적화를 가능하게합니다. 여전히 100 % 정확성을 유지합니다. -ffast-math
일반적으로 해를 끼치 지 않지만 표준의 표현에 의해 잘못된 것으로 간주 될 수있는 "약간 부정확 한"행동을 허용함으로써 수학 연산을 더 빠르게하려고 시도합니다. 코드가 참이면 많은 두 컴파일러 (단지 1 ~ 2 %)에 속도가 다른 다음 코드가 엄격하게 기준을 준수하는지 확인하고 ...
#pragma omp parallel for
루프 본문 내에서 함수 인수가 가리키는 주소를 읽고 쓰며 사소한 양의 분기를 수행합니다. 교육받지 못한 추측으로, 구현 정의 스레드 호출 내에서 캐시를 스 래싱 할 수 있으며 MSVC는 앨리어싱 규칙이 요구하는 중간 저장소를 잘못 피할 수 있습니다. 말할 수 없습니다.