Por que o GCC implementa isnan () com mais eficiência em C ++ <cmath> do que em C <math.h>?
Aqui está o meu código:
int f(double x)
{
return isnan(x);
}
Se eu#include <cmath>
Eu recebo esta montagem:
xorl %eax, %eax
ucomisd %xmm0, %xmm0
setp %al
Isso é razoavelmente inteligente:ucomisd define o sinalizador de paridade se a comparação de x consigo não for ordenada, o que significa que x é NAN. Entãosetp copia o sinalizador de paridade no resultado (apenas um byte, portanto, a limpeza inicial de%eax
)
Mas se eu#include <math.h>
Eu recebo esta montagem:
jmp __isnan
Agora o código não está embutido, e o__isnan
função certamente não é mais rápido o doucomisd
instruções, portanto, incorremos em um salto sem nenhum benefício. Eu recebo a mesma coisa se eu compilar o código como C.
Agora, se eu mudar oisnan()
ligar para__builtin_isnan()
, Eu entendo o simplesucomisd
instrução instrução, independentemente de qual cabeçalho eu incluo, e funciona em C também. Da mesma forma, se eu apenasreturn x != x
.
Então, minha pergunta é: por que o C<math.h>
cabeçalho fornecem uma implementação menos eficiente deisnan()
que o C ++<cmath>
cabeçalho? As pessoas realmente devem usar__builtin_isnan()
e, se sim, por quê?
Testei o GCC 4.7.2 e 4.9.0 em x86-64 com-O2
e-O3
otimização.