Was ist schneller? Assembler oder C++?



  • Hi,

    welche der beiden Funktionen sind schneller, und vorallem WARUM?

    inline void matrix::identity (void)
    {
    	this->_11 = this->_22 = this->_33 = this->_44 = 1.0f;
    	this->_12 = this->_21 = this->_31 = this->_41 = 
    	this->_13 = this->_23 = this->_32 = this->_42 = 
    	this->_14 = this->_24 = this->_34 = this->_43 = 0.0f;
    }
    
    		// vs.
    
    inline void matrix::identity (void)
    {
    	const float a = 1.0f; 
    	const float b = 0.0f; 
    
    	matrix *m = this;
    
    	__asm 
    	{ 
    		mov   eax, m
    		mov   ebx, a 
    		mov   ecx, b 
    
    		mov   [eax],ebx 
    		mov   [eax+14h],ebx 
    		mov   [eax+28h],ebx             
    		mov   [eax+3Ch],ebx  
    
    		mov   [eax+30h],ecx             
    		mov   [eax+0Ch],ecx             
    		mov   [eax+8],ecx           
    		mov   [eax+4],ecx             
    		mov   [eax+34h],ecx             
    		mov   [eax+1Ch],ecx             
    		mov   [eax+18h],ecx           
    		mov   [eax+10h],ecx           
    		mov   [eax+38h],ecx           
    		mov   [eax+2Ch],ecx           
    		mov   [eax+24h],ecx           
    		mov   [eax+20h],ecx 
    	} 
    
    	(*this) = (*m);
    }
    


  • Miss selber. Das ist der einzige Weg rauszufinden, was _auf Deinem System_ schneller ist.



  • SG1 schrieb:

    Miss selber. Das ist der einzige Weg rauszufinden, was _auf Deinem System_ schneller ist.

    Ich meinte eher eure persönliche Einstellung und nicht die Fakten 😃



  • Persönliche Einstellung? Cool, das habe ich noch nie verwendet..."Lieber Kunde ich weiß auch nicht warum unser Produkt bei Ihnen langsamer ist als $Konkurrenzprodukt, meien Einstellung zu der Sache ist dass unseres viel schneller ist" 😃

    Ich tippe hier aber ansonsten auf die C-Variante, insbesondere wenn ein intelligenter Compielr rangeht. Der kann das nämlich genausogut in movs umwandeln und da noch mehr rausholen wenn möglich.


  • Mod

    die C++ variante ist selbstverständlich schneller, weil der asm teil grober unfug ist (und was das this-> im C++ soll ist auch nicht klar)

    inline void matrix::identity (void)
    {
    	const float a = 1.0f; 
    	const float b = 0.0f; 
    
    	matrix *m = this;          // überflüssig
    
    	__asm 
    	{ 
    		mov   eax, m
    		mov   ebx, a 
    		mov   ecx, b 
    
    		mov   [eax],ebx 
    		mov   [eax+14h],ebx 
    		mov   [eax+28h],ebx             
    		mov   [eax+3Ch],ebx  
    
    		mov   [eax+30h],ecx             
    		mov   [eax+0Ch],ecx    // ganz         
    		mov   [eax+8],ecx           
    		mov   [eax+4],ecx 
    		mov   [eax+34h],ecx             
    		mov   [eax+1Ch],ecx    // schlecht         
    		mov   [eax+18h],ecx           
    		mov   [eax+10h],ecx           
    		mov   [eax+38h],ecx    // speicherzugriffe sollten       
    		mov   [eax+2Ch],ecx           
    		mov   [eax+24h],ecx    // sequentiell aufsteigend
    		mov   [eax+20h],ecx    // erfolgen wenn möglich
    	} 
    
    	(*this) = (*m);            // grober unfug, kopiert auf sich selbst
    }
    

    es bietet sich an

    inline void matrix::identity()
    {
    	const float a = 1.0f; 
    	const float b = 0.0f; 
    
    	__asm 
    	{ 
    		mov   eax, this
    		mov   ebx, a
    		mov   ecx, b
    
    		mov   [ eax + _11 ],ebx    // bzw in der reihenfolge _11, _21, _31 je nachdem wie die nummerierung geht
    		mov   [ eax + _12 ],ecx 
    		mov   [ eax + _13 ],ecx             
    		mov   [ eax + _14 ],ecx  
    		mov   [ eax + _21 ],ecx
    		mov   [ eax + _22 ],ebx 
    		mov   [ eax + _23 ],ecx             
    		mov   [ eax + _24 ],ecx  
    		mov   [ eax + _31 ],ecx
    		mov   [ eax + _32 ],ecx 
    		mov   [ eax + _33 ],ebx             
    		mov   [ eax + _34 ],ecx  
    		mov   [ eax + _41 ],ecx
    		mov   [ eax + _42 ],ecx 
    		mov   [ eax + _43 ],ecx             
    		mov   [ eax + _44 ],ebx  
    	} 
    }
    

    das ist auch nicht das gelbe vom ei aber...

    wenn es ein vector von matrizen ist, wäre es noch schneller sie vorher mittels rep stosd zu initialisieren und dann nur noch die hauptdiagonale zu überschreiben

    trotzdem wäre eine vernünftige C++ variante sinnvoller, da leichter zu warten und für den compiler besser zu analysieren (bei asm kann er register nicht umbenennen), das kann dazu führen, dass er sich weigert, den asm code tatsächlich inline einzufügen

    es böte sich an

    inline void matrix::identity ()
    {
        _44 = _33 = _22 = _11 = 1.0f;
              _43 = _42 = _41 =
        _34 =       _32 = _31 =
        _24 = _23 =       _21 =
        _14 = _13 = _12       = 0.0f;
    }
    


  • was noch zu beachten ist, dass ein guter c++ compiler nicht alle member initialisiert wenn gleich darauf diese werte verändert werden, beim assembler würde er das machen was angegeben ist.

    rapso->greets();


  • Mod

    yep

    ein weiterer nachteil von inline funktionen, die assembler blöcke benutzen, ist, dass der compiler immer eine lokale kopie von this anlegt (sonst könnte mov eax,this ja auch nicht funktionieren), register werden automatisch gesichert wenn nötig - es ist also zweckmäßig, möglichst wenige zu verwenden.

    dass this im ecx register zu finden ist, gilt so nur für thiscall funktionen, die naked sind

    wie gesagt, von inline assembler ist in inline funktionen generell abzuraten, wenn man es unbedingt braucht, sollte man besser ein macro benutzen


Anmelden zum Antworten