¿Obtengo una penalización de rendimiento al mezclar las instrucciones SIMD enteras/flotantes SSE
assembly intrinsics (1)
De un experto (obviamente no yo: P): http://www.agner.org/optimize/optimizing_assembly.pdf [13.2 Usar instrucciones de vectores con otros tipos de datos para los que están destinados (páginas 118-119)]:
Hay una penalización por usar el tipo incorrecto de instrucciones en algunos procesadores. Esto se debe a que el procesador puede tener diferentes buses de datos o diferentes unidades de ejecución para datos de punto flotante y enteros. El movimiento de datos entre las unidades de punto flotante y entero puede tomar uno o más ciclos de reloj según el procesador, como se indica en la tabla 13.2.
Processor Bypass delay, clock cycles Intel Core 2 and earlier 1 Intel Nehalem 2 Intel Sandy Bridge and later 0-1 Intel Atom 0 AMD 2 VIA Nano 2-3 Table 13.2. Data bypass delays between integer and floating point execution units
Últimamente he usado muchas instrucciones SIMD (SSE1234) en forma de intrínsecos. Lo que encontré frustrante es que el SSE ISA tiene varias instrucciones simples que están disponibles solo para flotadores o solo para enteros, pero en teoría deberían funcionar igual para ambos. Por ejemplo, tanto los vectores flotantes como los dobles tienen instrucciones para cargar 64 bits más altos de un vector de 128 bits desde una dirección ( movhps , movhpd ), pero no existe tal instrucción para los vectores enteros.
Mi pregunta:
¿Hay alguna razón para esperar un impacto en el rendimiento cuando se usan instrucciones de punto flotante en vectores enteros, por ejemplo, usando movhps para cargar datos en un vector entero?
Escribí varias pruebas para verificar eso, pero supongo que sus resultados no son creíbles. Es realmente difícil escribir una prueba correcta que explore todos los casos de esquinas para tales cosas, especialmente cuando la programación de instrucciones está probablemente involucrada aquí.
Pregunta relacionada:
Otras cosas trivialmente similares también tienen varias instrucciones que hacen básicamente lo mismo. Por ejemplo, puedo hacer bitwise OR con por , orps o orpd . ¿Alguien puede explicar cuál es el propósito de estas instrucciones adicionales? Supongo que esto podría estar relacionado con diferentes algoritmos de programación aplicados a cada instrucción.