Problema en programación con SSE2

Hola,

Tengo un problema con un código de SSE2 que no consigo entender. El trozo de código es el siguiente:

asm("movupd xmm1, [xp]");xp+=2;
asm("movupd xmm0 , [yp]");yp+=2;

asm("addpd xmm1, xmm0\n");

asm("movupd [yp], xmm1\n");

"yp" en ese momento pasa a ser null, lo que me dice que el culpable de que pase esto es el "addpd", puesto que si lo comento "yp" no llega a ser null en ningún momento. . ¿Alguien tiene alguna idea? LLevo varias horas con esto y no lo consigo ver...

Muchas gracias por adelantado!
¿Dónde apunta yp cuando se ejecuta esta instrucción?

movupd xmm0 , [yp]
En ese momento apunta a un double y va todo perfectamente normal. De hecho si imprimo el valor del puntero antes y después del último movupd, se ve que es justo en ese momento cuando pasa a ser una referencia no válida.
y si cambias las instrucciones

movupd por movapd
Tampoco, de todas formas creo que con movupd debería funcionar todo ¿no?
tu te has mirao esto por si acaso?
http://www.intel.com/software/products/documentation/vlin/mergedprojects/analyzer_ec/mergedprojects/reference_olh/mergedprojects/instructions/instruct32_hh/vc8a.htm

aunque creo que te da fallo en el SS segment = 0

mas concreto esto

Protected Mode Exceptions

#GP(0) - For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments. If memory operand is not aligned on a 16-byte boundary, regardless of segment.

#SS(0) - For an illegal address in the SS segment.
¿Cómo puedo saber si es alguna de esas? Creo que tengo esos arrays bien alineados.

El segundo no lo entiendo muy bien, yo creo que tengo todo bien, me estoy desesperando un poco ya :s
deberias probarlo con instrucciones convencionales a ver si pasa lo mismo ya sabes

asm("mov ebx, [xp]");xp+=2;
asm("mov eax , [yp]");yp+=2;

asm("add ebx, eax\n");

asm("mov [yp], ebx\n");


es que no se si sabes que estas usando doubled pack y son 128 bits unalign y sin precision
Pues justo... sigue pasando, por lo que no es problema de SSE sino de algo que hago mal yo. No se me había ocurrido probarlo así la verdad, dí por hecho que era eso.

No entiendo lo de que son sin precisión. ¿No se supone que instrucciones como movupd, addpd utilizan doble precisión? ¿Cuál crees que es el problema?
los datos sin precision suelen dar demasiados ceros (a veces) sobre todo si no se usan los de menor peso y no los de mayor

yo creo que el problema es la comprension de las instrucciones

add reg1,reg2
sumaba y depositaba el resultado en el reg1
excepto para una funcion especifica de add(que no recuerdo cual) que ademas sumaba y depositaba el resultado
en el EAX
despues de eso tenia que salvar el registro enviandolo a memoria o perdias el dato
push EAX
luego lo recuperabas con
pop EAX
Pero la cuestión es que ejemplos muy parecidos los he visto por ahí como correctos, por lo que me parece muy muy raro, por ejemplo:
http://www.gamedev.net/reference/articl ... le1987.asp
ese ejemplo difiere en el tuyo en que estas utilizando en tu programa 2 double y no tres

en el ejemplo pone
x,y,retval
el tuyo pone
xp,yp,(void)

no puedes usar yp 2 veces para 2 cometidos distintos

y deberias revisar la ia32 aunque parezca una chorrada se encuentran cosas como estas

10.2.3.3 Flush-To-Zero
Bit 15 (FZ) of the MXCSR register enables the flush-to-zero mode, which controls the
masked response to a SIMD floating-point underflow condition. When the underflow
exception is masked and the flush-to-zero mode is enabled, the processor performs
the following operations when it detects a floating-point underflow condition:
• Returns a zero result with the sign of the true result
• Sets the precision and underflow exception flags
If the underflow exception is not masked, the flush-to-zero bit is ignored.
The flush-to-zero mode is not compatible with IEEE Standard 754. The IEEEmandated
masked response to underflow is to deliver the denormalized result (see
Section 4.8.3.2, “Normalized and Denormalized Finite Numbers”). The flush-to-zero
mode is provided primarily for performance reasons. At the cost of a slight precision
loss, faster execution can be achieved for applications where underflows are common
and rounding the underflow result to zero can be tolerated.
The flush-to-zero bit is cleared upon a power-up or reset of the processor, disabling
the flush-to-zero mode.
10.2.3.4 Denormals-Are-Zeros
Bit 6 (DAZ) of the MXCSR register enables the denormals-are-zeros mode, which
controls the processor’s response to a SIMD floating-point denormal operand condition.
When the denormals-are-zeros flag is set, the processor converts all denormal
source operands to a zero with the sign of the original operand before performing any
computations on them. The processor does not set the denormal-operand exception
flag (DE), regardless of the setting of the denormal-operand exception mask bit
(DM); and it does not generate a denormal-operand exception if the exception is
unmasked.
The denormals-are-zeros mode is not compatible with IEEE Standard 754 (see
Section 4.8.3.2, “Normalized and Denormalized Finite Numbers”). The denormalsare-
zeros mode is provided to improve processor performance for applications such
as streaming media processing, where rounding a denormal operand to zero does
not appreciably affect the quality of the processed data.
The denormals-are-zeros flag is cleared upon a power-up or reset of the processor,
disabling the denormals-are-zeros mode.
The denormals-are-zeros mode was introduced in the Pentium 4 and Intel Xeon
processor with the SSE2 extensions; however, it is fully compatible with the SSE
Hola,

El usar "yp" por segunda vez lo he puesto aquí a efecto que lo viérais más claro, en mi programa sí uso una tercera declarada exactamente igual.

Sobre los números, ahora los relleno con un for como yp[i] =(double)(i+1);, no hay underflow ni números denormalizados.

edit: ¿Tienes alguien algún ejemplo en C simple y que esté completo para probarlo en mi máquina?

Saludos y muchas gracias!
ups mal vamos hace años que programo naaa
y tengo que volver a estudiar desde el principio
pero por lo menos el asm aun lo recuerdo
pero no creo que pudiese siquiera a dibujar un circulo en c
en estos momentos
13 respuestas