CRC32 errechnen mit SSE4.2

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

CRC32 errechnen mit SSE4.2

Beitrag von Thorium »

Da ich gerade SIMD Programmierung lerne habe ich mir mal die neuen SSE4 Instruktionen angeschaut und eine sehr interessante gefunden: CRC32.
Die tut genau das was ihr Name vermuten lässt und ist zudem sehr einfach zu verwenden. Also hab ich ne kleine Prozedur drumm gebastelt.

Allerdings handelt es sich dabei um einen anderen Typ von CRC32 als ihn PureBasic errechnet. Das heisst die SSE4.2 Prozedur und die PB-Routine sind nicht kompatibel zueinander und generieren unterschiedliche Ergebnisse.

Die Prozedur ist nicht sonderlich optimiert und soll auch nur als Beispiel dienen. Dennoch ist sie auf meinem Rechner 3 mal so schnell wie die PB Routine.

Um diesen Code nutzen zu können muss die CPU SSE4.2 unterstützen. Tut sie das nicht, crasht das Programm. Da es sich nur um ein Beispiel handelt habe ich auf Code der die SSE4.2 Unterstützung prüft verzichtet.

Ausserdem benötigt man um den Code zu kompilieren die neueste stabile FAsm Version. Kann man hier runterladen: http://www.flatassembler.net
Die alte FAsm.exe im "compilers" Ordner durch die neue ersetzen. Ansonsten kennt FAsm die CRC32 Instruktion nicht und wirft einen Assemblerfehler aus.

Code: Alles auswählen

Procedure.i CRC32_SSE4(*Buffer, Size.i, InitValue.i = -1 )

  CompilerSelect #PB_Compiler_Processor
 
    CompilerCase #PB_Processor_x86

      !push esi
   
      !mov esi,[p.p_Buffer+4]
      !mov ecx,[p.v_Size+4]
      !mov eax,[p.v_InitValue+4]
      !xor edx,edx
     
      !align 4
      !CRC32_SSE4_LoopStart:
       
        !mov dl,[esi]
        !crc32 eax,dl
       
        !inc esi
        !dec ecx
     
      !jne CRC32_SSE4_LoopStart
   
      !pop esi
   
    CompilerCase #PB_Processor_x64
   
      !push rsi
   
      !mov rsi,[p.p_Buffer+8]
      !mov rcx,[p.v_Size+8]
      !mov rax,[p.v_InitValue+8]
      !xor rdx,rdx
     
      !align 8
      !CRC32_SSE4_LoopStart:
       
        !mov dl,[rsi]
        !crc32 rax,dl
       
        !inc rsi
        !dec rcx
     
      !jne CRC32_SSE4_LoopStart
   
      !pop rsi

  CompilerEndSelect

  ProcedureReturn

EndProcedure
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Re: CRC32 errechnen mit SSE4.2

Beitrag von Rings »

ob eure CPU überhaupt SSE4 unterstützt,
könnt ihr durch
'Helle' 's Routine von hier

erfahren.
Meine CPU kanns net. ;(
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: CRC32 errechnen mit SSE4.2

Beitrag von Helle »

Habe die CPU-Info soeben aktualisiert.
@Thorium: Das Ergebnis liegt in "reflected bit order" (Bits 0-31 sind "vertauscht") vor, deshalb muss vor dem ProcedureReturn noch

Code: Alles auswählen

!not eax  
!bswap eax
eingefügt werden.

Gruß
Helle
Antworten