programing

왜 GCC는 C보다 C++에 대해 isnan()을 더 효율적으로 구현합니까?

batch 2023. 7. 5. 20:34
반응형

왜 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

반응형