warning C4799: function 'Interp3' has no EMMS instruction



  • Hi,

    ich habe folgenden Code aus einem Sample das ich vom Sinn her mit Assembler größtenteils verstehe, aber ich verstehe die daraus resultierende Level1-Warnung nicht.

    Hier erstmal code:

    inline void Interp3(unsigned char * pc, int c1, int c2)
    {
        //*((int*)pc) = (c1*7+c2)/8;
        __asm
        {
            mov        eax, pc
            movd       mm1, c1
            movd       mm2, c2
            punpcklbw  mm1, reg_blank
            punpcklbw  mm2, reg_blank
            pmullw     mm1, const7
            paddw      mm1, mm2
            psrlw      mm1, 3
            packuswb   mm1, reg_blank
            movd       [eax], mm1
        }
    }
    

    warning C4799: function 'Interp3' has no EMMS instruction

    Ich habe auf der MSDN gesucht, aber nichts passendes zu dieser Thematik gefunden für Thema inline Assembler und MMX.

    Daher meine Frage: Was muss an dem Code geändert werden, dass diese Level1-Warnung (die ich mehr mit Fehler gleichsetze) verschwindet und der Code korrekt ist?

    Großes Danke im voraus!

    p.s.: Ich benutze Visual C++ 2005.


  • Mod

    mmx und fpu (und 3dnow) instruktionen arbeiten mit dem selben registersatz. jede mmx operation maskiert automatisch den fpu stack (durch einen entsprechenden eintrag im tag register). damit folgende berechnungen die fpu benutzen können, muss der stack neu initialisiert werden. das kann durch finint bzw. fload passieren - aber das ist entsprechend langsam. für den speziellen fall des wechsels von mmx auf fpu instruktionen ist emms da, dieser befehl ist - vergleichsweise - schnell. trotzdem ist es eine schlechte idee mmx und fpu code zu mischen. andererseits benötigt der compiler die fpu für seine eigenen berechnungen. sse2 macht mmx und fpu weitgehend überflüssig - insofern ist die problematik heute nicht mehr sonderlich wichtig. die warnung entfernst du einfach, indem du am ende noch ein eine emms instruktion anfügst - das ist aber möglicherweise an dieser stelle nicht sinnvoll - wenn Interp3 teil einer grösseren operation ist. dann sollte emms erst am ende der gesamten berechnung benutzt werden. wie gesagt, emms ist zwar deutlich schneller als finit/fload - aber immer noch eine der weniger performanten instruktion.

    nebenbei bemerkt verträgt sich inline assembler nicht besonders gut mit inline funktionen, die parameter haben - zumindest bei non-gcc compilern.


Anmelden zum Antworten