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.htmlGruß
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