2010-08-31 5 views
5

Hay muchas pistas y afirmaciones de que la aritmética con NaN puede ser "lenta" en las FPU de hardware. Específicamente en la moderna FPU x64, por ejemplo en un Nehalem i7, ¿sigue siendo cierto? ¿Se multiplican las multiplicaciones de FPU a la misma velocidad, independientemente de los valores de los operandos?¿Qué tan lenta es la aritmética de NaN en la FPU Intel x64?

Tengo un código de interpolación que puede desviarse del borde de nuestros datos definidos, y estoy tratando de determinar si es más rápido verificar si hay NaN (o algún otro valor centinela) aquí y en todas partes, o simplemente en un conveniente puntos.

Sí, evaluaré mi caso en particular (podría estar dominado por otra cosa, como el ancho de banda de memoria), pero me sorprendió no ver un resumen conciso en algún lugar para ayudar con mi intuición.

Lo haré desde el CLR, si hace una diferencia en cuanto al sabor de los NaN generados.

+0

Por lo que yo sé, solo hay un valor 'NaN'. – zneak

+3

@zneak: Por lo menos, IEEE-754 define NaN "silenciosos" y "señalizadores" con diferentes patrones de bits. –

+0

@Jim Lewis Creo que eso fue más allá de lo que sabía. – zneak

Respuesta

6

Por lo que vale la pena, el uso de la instrucción SSE mulsd con NaN es casi igual de rápido que con la constante 4.0 (elegida por una tirada justa, garantizada al azar).

este código:

for (unsigned i = 0; i < 2000000000; i++) 
{ 
    double j = doubleValue * i; 
} 

genera el código máquina (dentro del bucle) con sonido metálico (supongo que la máquina virtual de .NET utiliza instrucciones SSE cuando puede también):

movsd  -16(%rbp), %xmm0 ; gets the constant (NaN or 4.0) into xmm0 
movl  -20(%rbp), %eax  ; puts i into a register 
cvtsi2sdq %rax, %xmm1   ; converts i to a double and puts it in xmm1 
mulsd  %xmm0, %xmm1  ; multiplies xmm0 (the constant) with xmm1 (i) 
movsd  %xmm1, -32(%rbp) ; puts the result somewhere on the stack 

Y con dos mil millones de iteraciones, el NaN (según lo definido por la macro C NAN de <math.h>) versión tomó aproximadamente 0.017 menos segundos para ejecutar en mi i7. La diferencia probablemente fue causada por el programador de tareas.

Para ser justos, son exactamente igual de rápidos.

+0

+1 para medir en lugar de adivinar! –

+0

Siempre es bueno ver los resultados de un perfil real de alguien, pero el OP pidió un resumen conciso y particular, no para una solución de referencia. Entonces -1. lo siento. FWIW, hice un punto de referencia en el compilador VS.2015 cl.exe y ejecutando dentro de un tiempo de ejecución mono (Unity 5.5.2, de hecho) y encontré que la prueba isNaN era ORDENES de magnitud más lenta. Entonces, solo porque encontraste un ejemplo donde su ayuno no responde la pregunta de si es generalmente tan rápido. – Imi

+0

@Imi, ¿has mirado el código que generó? Además, esta respuesta no tiene un isNaN en cualquier lugar. – zneak

Cuestiones relacionadas