Aktivierung der XMM und MM Intrinsics beim MinGW-3.3.1 Compiler



  • Hallo,

    ich habe ein großes Problem. Und zwar habe ich Code von Intel (4x4 Matrix Inversion) in mein Projekt importiert.

    Dieser Code ist auf Pentium3 Architektur optimiert, gebraucht also SSE Instruktionen. Intel verwendet in ihrem Code die bekannten Compilerintrinsics. Code importiert und versucht zu compilen, ging natürlich nicht da er die ganzen Intrinsics nicht kannte.

    Jedoch habe ich die Intrinsics-Header beim MinGW gefunden, also sollte das doch gehen. Hab also die Header manuell included, ging aber immer noch nicht da ein Error in den Headern erzeugt wurde, wenn __SSE__ nicht definiert war.

    Da der XMM Intrinsics Header gleichzeitig noch den MM Header eingebunden hab (und da __MMX__ definiert sein musste) hab ich kurzerhand vorm Einbinden von xmmintrin.h sowohl __SSE__ als auch __MMX__ definiert.

    Klappte auch ganz gut, allerdings kannte er nun seine ganzen builtin-Funktionen nicht mehr (die von den Intrinsics benutzt werden).

    Nun gut, dachte ich mir, jetzt gehste die Sache mal anders an. Mit -mmmx und -msse als Compilerflags übersetzt und jetzt meckerte er nur noch über doppelt definierte Symbole. Also __MMX__ und __SSE__ wieder entfernt und schon compilte er wunderbar.

    Allerdings crasht er jetzt beim Start der Anwendung. Er werdet nun denken, dass ich den Matrixinversioncode gleich verwende. Nein das tue ich nicht, da ich gar keine Maschine habe die SSE Code ausführt.
    Also sollte das ganze eigentlich ganz normal weiterlaufen, schliesslich wird noch kein MMX, SSE verwendet, dachte ich mir zumindestens.

    Doch ein kurzer Blick in das Assemblat überzeugte mich davon, dass die normale Inversionsmethode der 3x3 Matrix Klasse auf einmal ebenfalls SSE-Instruktionen (movss) verwendete.

    Komisch, da die Compilerflags nach dieser Anleitung als einziges die Freischaltung der Intrinsics zur Folge haben sollte. Nichts weiter sollte mit dem Code geschehen.

    So war das auch von mir intendiert gewesen. Das einzige was ich wollte war eben die Aktivierung der Intrinsics, der Compiler sollte aber nicht anfangen SSE-optimierten Code zu erzeugen (der auf meiner Maschine sowieso nicht lauffähig wäre). Anscheinend machen die Compilerflags aber nun doch mehr als sie eigentlich sollten, sie generieren nämlich Opcodes die auf eine SSE-Architektur zugeschnitten sind.

    Wie umgehe ich das? Ich will nur Intrinsics-Support haben, keine automatischen Optimierungen des restlichen Codes. Wäre nett, wenn mir da einer helfen könnte.

    Thx schonmal,
    liquidAcid



  • Hab gerade mal in den mingw Headern von Dev-C++ nachgeschaut und kann dort nix von __MMX__ und __SSE__ finden.

    LiquidAcid schrieb:

    Hab also die Header manuell included, ging aber immer noch nicht da ein Error in den Headern erzeugt wurde, wenn __SSE__ nicht definiert war.

    Sag mal genau, welcher Fehler erzeugt wird.



  • Hab gerade noch was in der Doku gefunden. Vielleicht solltest du dir dieses Compilerflag mal näher anschaun.

    To have SSE/SSE2 instructions generated automatically from floating-point code, see -mfpmath=sse.



  • groovemaster2002 schrieb:

    Hab gerade mal in den mingw Headern von Dev-C++ nachgeschaut und kann dort nix von __MMX__ und __SSE__ finden.

    LiquidAcid schrieb:

    Hab also die Header manuell included, ging aber immer noch nicht da ein Error in den Headern erzeugt wurde, wenn __SSE__ nicht definiert war.

    Sag mal genau, welcher Fehler erzeugt wird.

    Zieh dir die aktuelle MinGW Version und such in der nach der Datei xmmintrin.h, da findest du ganz am Anfang den entsprechenden Error (#error) der bei nichtdefiniertem Symbol erzeugt wird. Es ist also kein eigentlicher Compilerfehler, sondern einer der durch den C-Präprozessor ausgelöst wird.

    @fpmath-Compilerflag: Ja, genau das versuche ich ja zu verhindern. Ich habe mir den Code auch angeguckt, es werden im FP Bereich keine speziellen Opcodes generiert, ist alles schön x87 Standard. ABER er verwendet den SSE-Opcode movss und macht dazu noch Gebrauch von den xmmX Registern. Er optimiert ohne Zweifel (da er durch die xmm-Register ja noch mehr GPRs frei hat) aber das soll er nicht.

    Ich will als einziges nur die Intrinsics nutzen, mehr nicht.

    cya
    liquid



  • LiquidAcid schrieb:

    Zieh dir die aktuelle MinGW Version und such in der nach der Datei xmmintrin.h, da findest du ganz am Anfang den entsprechenden Error (#error) der bei nichtdefiniertem Symbol erzeugt wird.

    Ich sollte wohl MinGW mal wieder aktualisieren. 😃

    Poste mal deine kompletten Compilerflags. Und an welcher Stelle genau generiert er SSE Instruktionen?



  • Compilerflags: -g3 -Wall

    Stelle: Einfache Zuweisungsoperationen werden durch die xmm-Register geschleust.

    Genau: Ich habe eine Colorspace-Konvertierungsklasse, die hat ein paar statische Member (die also vor main initialisiert werden) und da wird eine 3x3 Matrixinversion benötigt. movss kommt zum Einsatz wenn die reziproke Determinante mit den Kofaktoren multipliziert wird und auch wenn das Ergebnis zurückgegeben wird.

    Achtung! Es wird normaler x87 Code für die FPU generiert, das einzige was ich entdeckt habe ich die Nutzung der xmm-Register zur temporären Speicherung bzw. als GPR Erweiterung. Er generiert keinen speziellen SSE FP Code, dafür zieht er sich mehr GPRs durch die zusätzlichen xmm-Register an Lande.

    cya
    liquid



  • LiquidAcid schrieb:

    Compilerflags: -g3 -Wall

    Ist das alles? Ich dachte du wolltest die builtin SSE Funktionen nutzen. Hab ich zwar selbst noch nicht gemacht, aber sollte da nicht zumindest noch -msse angegeben werden.
    Versuch mal explizit -march=i686 noch anzugeben. Dann sollte gcc eigentlich maximal MMX Befehle verwenden.



  • Das sind die Compilerflags die für das gesamte Projekt gelten. Da ich Intrinsics nur in einer bestimmten Source-Datei brauche wird es auch nur dort aktiviert.

    @Arch-Parameter: Werde ich mal ausprobieren.

    cya
    liquid


Anmelden zum Antworten