왜 GCC는 C보다 C++ 에 대해 isnan()을 더 효율적으로 구현합니까?
내 코드는 다음과 같습니다.
int f(double x)
{
return isnan(x);
}
내가 만약에#include <cmath>
나는 이 어셈블리를 받습니다.
xorl %eax, %eax
ucomisd %xmm0, %xmm0
setp %al
이것은 상당히 영리합니다. ucomisd는 x와 자체의 비교가 순서가 없는 경우 패리티 플래그를 설정합니다. 즉, x는 NAN입니다.그런 다음 setp는 패리티 플래그를 결과로 복사합니다(단일 바이트만, 따라서 초기 지우기).%eax
).
하지만 내가#include <math.h>
나는 이 어셈블리를 받습니다.
jmp __isnan
이제 코드는 인라인이 아니며,__isnan
기능은 확실히 더 빠르지 않습니다.ucomisd
교육, 그래서 우리는 아무런 이익도 없이 점프를 발생시켰습니다.코드를 C로 컴파일하면 같은 것을 얻을 수 있습니다.
이제 내가 바꾸면,isnan()
로 불러들입니다.__builtin_isnan()
나는 간단한 것을 이해합니다.ucomisd
어떤 헤더를 포함하든 상관없이 명령 명령어는 C에서도 작동합니다.마찬가지로 내가 그냥return x != x
.
그래서 제 질문은, 왜 C가<math.h>
헤더는 보다 효율적인 구현을 제공합니다.isnan()
C++ 보다<cmath>
헤더?사람들이 정말로 사용하기를 기대합니까?__builtin_isnan()
그리고 만약 그렇다면, 왜?
x86-64에서 GCC 4.7.2 및 4.9.0을 테스트했습니다.-O2
그리고.-O3
최적화
을 살피는 것<cmath>
gcc 4.9와 함께 제공되는 libstdc++의 경우 다음과 같은 정보를 얻을 수 있습니다.
constexpr bool
isnan(double __x)
{ return __builtin_isnan(__x); }
A constexpr
함수는 공격적으로 인라인화될 수 있으며, 물론 함수는 작업을 위임합니다.__builtin_isnan
.
그<math.h>
헤더가 사용되지 않음__builtin_isnan
오히려 그것은 사용합니다.__isnan
여기에 붙이기에는 다소 긴 구현이지만 430행입니다.math.h
내 기계에서 ™.C99 표준은 다음을 위해 매크로를 사용해야 하기 때문입니다.isnan
기타(C99 표준의 섹션 7.12) '기능'은 다음과 같이 정의됩니다.
#define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \
: sizeof (x) == sizeof (double) ? __isnan (x) \
: __isnanl (x))
하지만, 나는 그것이 사용할 수 없는 이유를 찾지 못합니다.__builtin_isnan
대신에__isnan
그래서 저는 그것이 실수라고 생각합니다.Marc Glisse가 코멘트에서 지적했듯이, 유사한 문제에 대한 관련 버그 보고서가 있습니다.isinf
대신에isnan
.
언급URL : https://stackoverflow.com/questions/26052640/why-does-gcc-implement-isnan-more-efficiently-for-c-cmath-than-c-math-h
'programing' 카테고리의 다른 글
리눅스에서 스레드 이름을 지정하는 방법은 무엇입니까? (0) | 2023.07.10 |
---|---|
Apple은 사용자가 개인 API를 사용하고 있는지 어떻게 알 수 있습니까? (0) | 2023.07.10 |
스프링 부트:이 리소스에 액세스하려면 전체 인증이 필요합니다. (0) | 2023.07.05 |
Spring Data JPA에서 페이지 생성 (0) | 2023.07.05 |
Oracle JDBC Thin Client 식별자 변경 (0) | 2023.07.05 |