significado procesador mexico lon error assembly x86 sse

assembly - procesador - ¿Qué significa comparación ordenada/desordenada?



sse wikipedia (4)

¿Quizás esta página sobre intrínsecos de Visual C ++ puede ser de ayuda? :)

CMPORDPS

r0 := (a0 ord? b0) ? 0xffffffff : 0x0 r1 := (a1 ord? b1) ? 0xffffffff : 0x0 r2 := (a2 ord? b2) ? 0xffffffff : 0x0 r3 := (a3 ord? b3) ? 0xffffffff : 0x0

CMPUNORDPS

r0 := (a0 unord? b0) ? 0xffffffff : 0x0 r1 := a1 ; r2 := a2 ; r3 := a3

Mirando los operadores SSE

CMPORDPS - ordered compare packed singles CMPUNORDPS - unordered compare packed singles

¿Qué significa ordenado y desordenado? Busqué instrucciones equivalentes en el conjunto de instrucciones x86, y solo parece haber desordenado (FUCOM).


Esta guía de Intel: http://intel80386.com/simd/mmx2-doc.html contiene ejemplos de los dos que son bastante sencillos:

CMPORDPS compara los paralelos ordenados paralelos

Instrucción de ciclos de códigos de operación 0F C2 .. 07 2 (3) CMPORDPS xmm reg, xmm reg / mem128

CMPORDPS op1, op2

op1 contiene 4 valores de coma flotante de 32 bits de precisión simple op2 contiene 4 valores de coma flotante de 32 bits de precisión simple

op1[0] = (op1[0] != NaN) && (op2[0] != NaN) op1[1] = (op1[1] != NaN) && (op2[1] != NaN) op1[2] = (op1[2] != NaN) && (op2[2] != NaN) op1[3] = (op1[3] != NaN) && (op2[3] != NaN) TRUE = 0xFFFFFFFF FALSE = 0x00000000

CMPUNORDPS compara los escalares paralelos desordenados

Instrucción de ciclos de código de operación 0F C2 .. 03 2 (3) CMPUNORDPS xmm reg, xmm reg / mem128

CMPUNORDPS op1, op2

op1 contiene 4 valores de coma flotante de 32 bits de precisión simple op2 contiene 4 valores de coma flotante de 32 bits de precisión simple

op1[0] = (op1[0] == NaN) || (op2[0] == NaN) op1[1] = (op1[1] == NaN) || (op2[1] == NaN) op1[2] = (op1[2] == NaN) || (op2[2] == NaN) op1[3] = (op1[3] == NaN) || (op2[3] == NaN) TRUE = 0xFFFFFFFF FALSE = 0x00000000

La diferencia es AND (ordenada) frente a OR (desordenada).


Una comparación ordenada comprueba si ninguno de los operandos es NaN . Por el contrario, una comparación desordenada comprueba si alguno de los operandos es un NaN .

Esta página ofrece más información sobre esto:

La idea aquí es que las comparaciones con NaN son indeterminadas. (no puede decidir el resultado) Entonces una comparación ordenada / desordenada verifica si este es (o no) el caso.

double a = 0.; double b = 0.; __m128d x = _mm_set1_pd(a / b); // NaN __m128d y = _mm_set1_pd(1.0); // 1.0 __m128d z = _mm_set1_pd(1.0); // 1.0 __m128d c0 = _mm_cmpord_pd(x,y); // NaN vs. 1.0 __m128d c1 = _mm_cmpunord_pd(x,y); // NaN vs. 1.0 __m128d c2 = _mm_cmpord_pd(y,z); // 1.0 vs. 1.0 __m128d c3 = _mm_cmpunord_pd(y,z); // 1.0 vs. 1.0 __m128d c4 = _mm_cmpord_pd(x,x); // NaN vs. NaN __m128d c5 = _mm_cmpunord_pd(x,x); // NaN vs. NaN cout << _mm_castpd_si128(c0).m128i_i64[0] << endl; cout << _mm_castpd_si128(c1).m128i_i64[0] << endl; cout << _mm_castpd_si128(c2).m128i_i64[0] << endl; cout << _mm_castpd_si128(c3).m128i_i64[0] << endl; cout << _mm_castpd_si128(c4).m128i_i64[0] << endl; cout << _mm_castpd_si128(c5).m128i_i64[0] << endl;

Resultado:

0 -1 -1 0 0 -1

  • La comparación ordenada de NaN y 1.0 da false .
  • La comparación desordenada de NaN y 1.0 da true .
  • La comparación pedida de 1.0 y 1.0 da true .
  • La comparación desordenada de 1.0 y 1.0 da false .
  • La comparación ordenada de NaN y Nan da false .
  • La comparación desordenada de NaN y NaN da true .

TL: DR : Desordenado es una relación que pueden tener dos valores FP. El "Desordenado" en FUCOM significa que no FUCOM una excepción FP cuando el resultado de la comparación no está ordenado, mientras que FCOMFCOM hace. Esto es lo mismo que la distinción entre predicados cmpps OQ y OS

ORD y UNORD son dos elecciones de predicado para las cmppd / cmpps / cmpss / cmpsd (tablas completas en la entrada cmppd que es alfabéticamente primero) . Ese extracto html tiene formato de tabla legible, pero el original PDF original de Intel es algo mejor. (Consulte la wiki de la etiqueta x86 para ver los enlaces).

Dos operandos de coma flotante se ordenan entre sí si ninguno es NaN . No están ordenados si alguno de ellos es NaN. es decir, ordered = (x>y) | (x==y) | (x<y); ordered = (x>y) | (x==y) | (x<y); . Así es, con punto flotante es posible que ninguna de esas cosas sea verdad. Para más locura de punto flotante, vea la excelente serie de artículos de Bruce Dawson.

cmpps toma un predicado y produce un vector de resultados, en lugar de hacer una comparación entre dos escalares y banderas de configuración para que pueda verificar cualquier predicado que desee después del hecho. Por lo tanto, necesita predicados específicos para todo lo que pueda verificar.

El equivalente escalar es comiss / ucomiss para configurar ZF / PF / CF a partir del resultado de la comparación FP (que funciona como las instrucciones de comparación x87 (ver la última sección de esta respuesta), pero en el elemento bajo de las reglas XMM).

Para verificar si no está ordenado, mira PF . Si la comparación está ordenada, puede mirar las otras banderas para ver si los operandos fueron mayores, iguales o menores ( usando las mismas condiciones que para los enteros sin signo, como jae para Above o Equal ).

La instrucción COMISS difiere de la instrucción UCOMISS en que señala una excepción de operación inválida de coma flotante SIMD (#I) cuando un operando fuente es QNaN o SNaN. La instrucción UCOMISS señala una excepción numérica inválida solo si un operando fuente es un SNaN.

Normalmente, las excepciones de FP están enmascaradas, por lo que esto no interrumpe realmente su programa; simplemente establece el bit en el MXCSR que puedes verificar más tarde.

Esto es lo mismo que los sabores de predicado O / UQ frente a O / US para cmpps / vcmpps . La versión AVX de las instrucciones cmp[ps][sd] tiene una opción expandida de predicado, por lo que necesitaban una convención de nomenclatura para realizar un seguimiento de ellos.

La O vs. U le dice si el predicado es verdadero cuando los operandos están desordenados.

La Q vs. S le dice si # I se generará si cualquiera de los dos operandos es un NaN silencioso. # Siempre me plantearé si alguno de los operandos es un NaN de señalización, pero esos no son "naturales". No los obtiene como salidas de otras operaciones, solo creando el patrón de bits usted mismo (por ejemplo, como un valor de retorno de error de una función, para asegurar la detección de problemas más adelante).

El equivalente x87 está usando fucom o fucom para configurar la palabra de estado FPU -> fstsw ax -> sahf , o preferiblemente fucomi para establecer EFLAGS directamente como comiss .

La distinción U / no U es la misma con las instrucciones x87 que con comiss / ucomiss