Gelöst: Meldung ML.exe "Statement too complex" + SSE Fehler
-
Guten Abend zusammen,
Ich erstelle ein Variablenarray und erhalte beim kompilieren diese Meldung.
In meinem bisherigen Programm waren diese Daten wie folgt angelegt:
koo dd 250.0 dd 50.0 dd 250.0 dd 60.0 dd 250.0 dd 70.0 dd 250.0 dd 80.0 dd 250.0 dd 90.0 dd 250.0 dd 100.0 dd 250.0 dd 110.0 dd 250.0 dd 120.0 dd 250.0 dd 130.0 dd 250.0 dd 140.0 dd 250.0 dd 150.0
Davon standen etwa 150 Einträge untereinander...
(Das sind alles Koordinaten von Bildschirmpunkten X,Y und Z immer im Wechsel)Ich möchte mein "Array" nun aber getrennt nach X, Y und Z anlegen:
koox dd 250.0,270.0,330.0,330.0,350.0,350.0,330.0,270.0,270.0,250.0,250.0,290.0,290.0,310.0,310.0,290.0,330.0
und zwar eben diese 150 Einträge... ab dem 51. Eintrag erhalte ich aber diese Meldung.
Habe ich hier was übersehen?
Gruß, Nicky
-
1. benutz die richtige Typ: REAL4. DD/DQ/DT akzeptieren FP Werte nur aus Kompatibilitätsgründen.
2. MASM hat eine maximale Zeilenlänge, die bei ca. 260 Zeichen liegt. Du musst die Zeile aufteilen.
-
masm schrieb:
1. benutz die richtige Typ: REAL4. DD/DQ/DT akzeptieren FP Werte nur aus Kompatibilitätsgründen.
2. MASM hat eine maximale Zeilenlänge, die bei ca. 260 Zeichen liegt. Du musst die Zeile aufteilen.Hallo,
Array funktioniert...
Nun habe ich meinen FPU Abschnitt nach SSE umgeschrieben... Leider verabschiedet sich hierbei die Anwendung
mov edi, offset koox ;EDI = X Wert mov esi, offset kooy ;ESI = Y Wert mov ecx,13d drehenlinks: .xmm ;fld dword ptr [edi] ;fsub mm_x ;fstp dword ptr [edi] movups xmm0, [edi] subps xmm0, [mm_x] movups [edi], xmm0 ;fld dword ptr [esi] ;fsub mm_y ;fstp dword ptr [esi] movups xmm0, [esi] subps xmm0, [mm_y] movups [esi], xmm0 ;fld dword ptr [edi] ;fmul cos1 movups xmm1, [edi] mulps xmm1, [cos1] ;fld dword ptr [esi] ;fmul sin1 movups xmm0, [esi] mulps xmm0, [sin1] ;fsub subps xmm1, xmm0 ;fadd mm_x addps xmm1, [mm_x] ;fstp tmpx movups [tmpx], xmm1 ;fld sin1 movups xmm0, [edi] ;fmul dword ptr [edi] mulps xmm0, [sin1] ;fld cos1 movups xmm1, [esi] ;fmul dword ptr [esi] mulps xmm1, [cos1] ;fadd addps xmm0, xmm1 ;fadd mm_y addps xmm0, [mm_y] ;fstp dword ptr [esi] movups [esi], xmm0 ;fld tmpx movups xmm0, [tmpx] ;fstp dword ptr [edi] movups [edi], xmm0 .486 add edi, 16d add esi, 16d dec ecx jnz drehenlinks
SSE rechnet das selbe wie die auskommentierten FPU Befehle. (Sollte zumindest)
Für einen Tipp bin ich wie immer sehr dankbar...
Gruß, Nicky
-
was sagt den dein Debugger(z.B. OllyDbg) dazu?
Ich geh davon aus das es am alignment scheiter: die vektoriellen (packed) Befehle (add/sub/mulps) benötigen ebenfalls ein alignment von 16.
Die jetzige Implementation ist höchstwahrscheinlich wesentlich langsamer als die FPU Version: sorg für das richte Ausrichtung und verwerf MOVUPS. Außerdem hast du 8 XMM Register zur Verfügung: genügend Platz um Zwischenergebnisse zu halten:movaps xmm0, [edi] ; x movaps xmm1, [esi] ; y subps xmm0, [mm_x] ; dx = x-mm_x subps xmm1, [mm_y] ; dy = y-mm_y movaps xmm2,xmm0 movaps xmm3,xmm1 mulps xmm0,[cos1] ; = dx*cos(1°) mulps xmm1,[sin1] ; = dy*sin(1°) mulps xmm2,[sin1] ; = dx*sin(1°) mulps xmm3,[cos1] ; = dy*cos(1°) subps xmm0,xmm1 ; dx*cos(1°) - dy*sin(1°) addps xmm2,xmm3 ; dx*sin(1°) + dy*cos(1°) addps xmm0,mm_x ; dx*cos(1°) - dy*sin(1°) + mm_x addps xmm2,mm_y ; dx*sin(1°) + dy*cos(1°) + mm_y movaps [edi], xmm0 movaps [esi], xmm2
-
BTW: den Befehlssatz wählt man einmal am Anfang des Quellcodes aus (.486, .xmm). Das'd'-Suffix ist im Übrigen auch sehr gewöhnungsbedürftig, zumal es keine Sicherheit gibt (nur das 't'-Suffix ist eindeutig ;-)).
-
Hallo,
Die Anweisung .486 würde tatsächlich am Anfang ausreichen, jedoch muss
ich .xmm unmittelbar vor den Code setzen der SSE Befehle enthält.
Ich erhalte sonst jede Zeile mit SSE Befehlen beim kompilieren als Fehler angezeigt..486 .model flat, stdcall .xmm option casemap :none include ..\include\windows.inc include ..\include\kernel32.inc
------------------------------
.code .xmm start: call Init call Main invoke ExitProcess,eax
Ist beides nicht möglich...
Jedenfalls habe ich mir deinen Hinweis, das auch subps, addps, divps die
Ausrichtung brauchen nochmal überlegt und habe den Code etwas umgeschrieben:mov edi, offset koox ;EDI = X Wert mov esi, offset kooy ;ESI = Y Wert mov ecx,13d ;Gesamtzahl des Array in Byte / 16 ergibt die Anzahl der Punkte drehenlinks: .xmm movups xmm0, [edi] movups xmm1, [mm_x] subps xmm0, xmm1 movups [edi], xmm0 movups xmm0, [esi] movups xmm1, [mm_y] subps xmm0, xmm1 movups [esi], xmm0 movups xmm0, [edi] movups xmm1, [cos1] mulps xmm0, xmm1 movups xmm1, [esi] movups xmm2, [sin1] mulps xmm1, xmm2 subps xmm0, xmm1 movups xmm1, [mm_x] addps xmm1, xmm0 movups [tmpx], xmm1 movups xmm0, [edi] movups xmm1, [sin1] mulps xmm0, xmm1 movups xmm1, [esi] movups xmm2, [cos1] mulps xmm1, xmm2 addps xmm0, xmm1 movups xmm1, [mm_y] addps xmm0, xmm1 movups [esi], xmm0 movups xmm0, [tmpx] movups [edi], xmm0 .486 add edi, 16d add esi, 16d dec ecx jnz drehenlinks
Die einzigste Möglichkeit ist die Daten für jede Operation erst in die
Register zu schreiben und dann den mathematischen Befehl nur auf die Register
anzuwenden. So läuft es jedenfalls bei mir ohne Probleme.Aus irgendeinem Grund bekomme ich mit movaps keine Daten in die Register
geschrieben, dann stürzt das Programm ab.Die Anweisung ALIGN 16 habe ich auch schon überall mal platziert gehabt,
jedoch immer Absturz des Programms.Ob es langsamer ist als der FPU Teil weiß ich nicht, ich denke die WinApi
tut ihr bestes um das Programm etwas zu bremsenGruß, Nicky
-
masm schrieb:
Die jetzige Implementation ist höchstwahrscheinlich wesentlich langsamer als die FPU Version: sorg für das richte Ausrichtung und verwerf MOVUPS.
Hallo masm,
ich habe mal mit QueryPerformanceCounter (versucht) die Geschwindigkeit
des SSE Abschnittes und des FPU Abschnittes zu messen..Wenn ich jeweils Anfangs- und Endwert subtrahiere erhalte ich bei
SSE zwischen 3 und 4, bei FPU zwischen 9 - 12.Von der Geschwindigkeit her lohnt sich SSE, da ich anstatt 64 Schleifendurchgänge (FPU) nur 16 mit SSE brauche.
Gruß, Nicky