[performance] gcc의 빠른 수학은 실제로 무엇을 하는가?

나는 gcc를 이해한다 --ffast-math 플래그가 플로트 op의 속도를 크게 높이고 IEEE 표준을 벗어나는 것을 알고 있지만 실제로 켜져있을 때 발생하는 정보에 대해서는 찾을 수 없습니다. 누구든지 세부 사항 중 일부를 설명하고 깃발이 켜져 있거나 꺼져 있으면 어떻게 변할 것인지에 대한 명확한 예를 제시 할 수 있습니까?

비슷한 질문에 대해 SO를 파고 들었지만 ffast-math의 작동을 설명하는 것을 찾을 수 없었습니다.



답변

언급했듯이 엄격한 IEEE 준수를 유지하지 않는 최적화가 가능합니다.

예를 들면 다음과 같습니다.

x = x*x*x*x*x*x*x*x;

x *= x;
x *= x;
x *= x;

부동 소수점 산술은 연관성이 없으므로 연산의 순서 및 인수 분해는 반올림으로 인한 결과에 영향을줍니다. 따라서이 최적화는 엄격한 FP 동작에서 수행되지 않습니다.

실제로 GCC가 실제로이 특정 최적화를 수행하는지 확인하지 않았습니다. 그러나 아이디어는 동일합니다.


답변

-ffast-math 엄격한 IEEE 준수를 깨뜨리는 것 이상을 수행합니다.

우선, 물론 깨집니다 엄격한 IEEE 준수를 , 예를 들어 부동 소수점에서 수학적으로 동일하지만 (이상적으로) 동일하지 않은 것으로 명령을 재정렬 할 수 있습니다.

둘째, 단일 명령어 수학 함수 후에 설정 을 비활성화 합니다 errno. 이는 스레드 로컬 변수에 대한 쓰기를 피함을 의미합니다 (일부 아키텍처에서 해당 함수에 대해 100 % 차이를 만들 수 있음).

셋째, 모든 수학이 유한 한 것으로 가정합니다. 즉 , 해로운 영향을 미칠 수있는 NaN (또는 0) 검사가 수행되지 않습니다. 이것은 일어나지 않을 것이라고 간단히 가정합니다.

넷째, 나누기와 역 제곱근에 대한 역 근사 를 가능하게 합니다.

또한 부호있는 0 (목표가 지원하더라도 부호있는 0이 존재하지 않는다고 가정) 및 반올림 수학을 비활성화하여 컴파일 타임에 일정하게 접을 수 있습니다.

마지막으로,이 더 하드웨어 인터럽트 때문에 수학을 트래핑 / 신호 일어날 수 있다고 가정 코드 생성 (이 결과적으로 목표 아키텍처에서 사용할 수 있고 할 수없는 경우입니다 일어나지 않는을 , 그들은 처리되지 않습니다).


답변