SSE



  • ich hab die ganze Zeit rumgegoogelt und nichts wirklich nützliches gefunden die sse anzusprechen.
    im prinzip muss man ja anfang prüfen, ob die cpu das kann. außerdem hab ich noch woanders gelesen, dass das betriebssystem das unterstützen muss, da das bs dafür sorgen muss, dass die benutzten fpu-register wieder aufräumen muss.

    wäre interessant eure tipps zu hören

    heimschmiede



  • Hallo,

    ich finde, die Intel Doku dazu reicht vollkommen aus.
    Falls du Assembler programmieren als Hobby machst, reicht es wenn du weisst, dass deine CPU SSE kann und kannst loslegen. Musst nur aufpassen, wenn ein SSE Befehl die Daten 16 Byte aligned haben möchte, dann musst du die Daten 16 Byte aligned anlegen, sonst bricht das Programm sofort ab, zumindest unter Linux, und du suchst lange nach dem Fehler...
    Ich benutze GNU Assembler unter Linux und Linux unterstützt SSE (im Sinne xmm-Register retten und so was). Würde mich sehr wundern, wenn nicht... ich denke, jedes modernere Betriebssystem unterstützt SSE.
    Wundere dich nicht über die Genauigkeit der SSE Rechenbefehle, ich hatte mich hier schon mal gewundert...: http://www.c-plusplus.net/forum/viewtopic-var-t-is-157859.html

    Gruß
    abc.c



  • Heimschmiede schrieb:

    ich hab die ganze Zeit rumgegoogelt und nichts wirklich nützliches gefunden die sse anzusprechen.
    im prinzip muss man ja anfang prüfen, ob die cpu das kann. außerdem hab ich noch woanders gelesen, dass das betriebssystem das unterstützen muss, da das bs dafür sorgen muss, dass die benutzten fpu-register wieder aufräumen muss.

    wäre interessant eure tipps zu hören

    heimschmiede

    Zeig dir mal ein Beispiel , wie man in einer Assemler-Routine prüft ob SSE2 verfügbar ist u.a..

    #include "stdafx.h"
    
    #define DIM 1401
    
    extern "C" void fcopy(void* dest, void* source, size_t len);
    
    int main()
    {
    __declspec(align(16)) int buf1[DIM];
    __declspec(align(16)) int buf2[DIM];
    
        for (int i = 0; i < DIM; i++){
            buf1[i] = i;
        }
    
        fcopy(buf2, buf1, sizeof buf1);
    
        return 0;
    }
    

    ...

    .586
    .xmm
    .model flat, c
    .code              
    
            public fcopy 
    
    fcopy proc c uses edi esi dest:near, source:near, count:dword
    
            mov         ecx, count 
            mov         esi, source
            mov         edi, dest
            cmp         ecx, 100h    ; block size greater than min threshold?
            jb          oldcopy
            extern      __sse2_available:dword		
            cmp         __sse2_available, 0
            je          oldcopy
            push        edi
            push        esi 
            and         esi, 01111b
            and         edi, 01111b
            sub         esi, edi	 
            pop         esi
            pop         edi 
            jne         oldcopy		 ; alignments equal?
            shr         ecx,7  
            jmp         fastcopy
    align 16
    fastcopy :        
            movdqa      xmm0, [esi] 
            movdqa      xmm1, [esi+10h] 
            movdqa      xmm2, [esi+20h] 
            movdqa      xmm3, [esi+30h] 
            movdqa      [edi], xmm0 
            movdqa      [edi+10h], xmm1 
            movdqa      [edi+20h], xmm2 
            movdqa      [edi+30h], xmm3 
            movdqa      xmm4, [esi+40h] 
            movdqa      xmm5, [esi+50h] 
            movdqa      xmm6, [esi+60h] 
            movdqa      xmm7, [esi+70h] 
            movdqa      [edi+40h], xmm4 
            movdqa      [edi+50h], xmm5 
            movdqa      [edi+60h], xmm6 
            movdqa      [edi+70h], xmm7 
            lea         esi, [esi+80h] 
            lea         edi, [edi+80h] 
            dec         ecx  
            jne         fastcopy 
            mov         ecx, count
            and         ecx, 01111111b		
    oldcopy :
            push        ecx
            shr         ecx, 2
            rep movsd
            pop         ecx        
            and         ecx, 011b
            rep movsb
            ret
    
    fcopy endp
    
        end
    

    mfg



  • super, danke!
    es läauft soweit recht rund bei mir. allerdings benötige ich die sse1, sodass deine prüfung von sse2 helmut mir nichts bringt. ich hab aber einen guten test über CPUID gefunden.

    public is_sse_supported
    
    is_sse_supported:
    	mov eax, 1     ;CPUID mit Parameter 1
    	CPUID
    	mov eax, edx   ;Die SSE-Info an Bit 25 in EDX
    	shr eax, 25    ;durchshiften
    	and eax, 1     ;und das Bit isolieren; Rückgabe ist ein bool
    	ret
    
    end
    

    was passiert eigentlich, wenn man die sse-befehle ausführt, obwohl kein sse vorhanden ist ?? undefiniert? oder fehler? oder sonstwas?

    heimschmiede



  • was passiert eigentlich, wenn man die sse-befehle ausführt, obwohl kein sse vorhanden ist ?? undefiniert? oder fehler? oder sonstwas?

    Unter Linux wird das Programm sofort abgebrochen und die Fehlermeldung "Unknown instruction" o.ä. ausgegeben.



  • Und unter Windows wird eine Exception vom Typ EXCEPTION_ILLEGAL_INSTRUCTION geworfen.



  • Und allgemein gibt's einfach eine Exception 06 (unknown OpCode).



  • Heimschmiede schrieb:

    public is_sse_supported
    
    is_sse_supported:
    	mov eax, 1     ;CPUID mit Parameter 1
    	CPUID
    	mov eax, edx   ;Die SSE-Info an Bit 25 in EDX
    	shr eax, 25    ;durchshiften
    	and eax, 1     ;und das Bit isolieren; Rückgabe ist ein bool
    	ret
    	
    end
    

    heimschmiede

    Dein Code testet das 26. Bit (sse2), um das 25. Bit (sse) zu testen muss man eax 24 mal nach rechts shiften, dann
    steht das 25. Bit an Position 1 und kann mit and eax,1 isoliert werden.



  • naja, es ist ja das 25. Bit aus einer Folge, die mit dem 0.Bit beginnt.
    wenn meine info in Bit0 liegen würde müsste 0-mal shiften und bei Bit25 muss ich dann ja 25 mal shiften.
    meine quelle ist folgende seite:
    http://www.sandpile.org/ia32/cpuid.htm
    die info steht in "standard level 0000_0001h" - EDX - Bit25
    also zusammenfassend ist es das 26. Bit (von 1 beginnend) und das 25.Bit (von 0 beginnend)
    oder versteh ich da was falsch?

    heimschmiede


Anmelden zum Antworten