Bit Reverse Algorithmus
Da ich gerade mit FFT arbeite brauche ich eine Funktion, die schnell die Bitumkehrung eines Wertes variabler Bitbreite zurückgibt.
von MSB->LSB zu LSB->MSB zur Zeit habe ich folgende Umsetzungen: Variante 1:
Delphi-Quellcode:
Variante 2:
function BitRev(inBit{eax}: Cardinal; BitCount{edx}: integer): Cardinal;
asm xor ecx, ecx // ecx := 0 test edx, edx // ist edx = 0? jz @Ende // wenn ja springe zu Ende @Loop: shr eax, 1 // eax nach rechts schieben -> unterstes Bit ins Carry-Flag rcl ecx, 1 // ecx nach links über Carry rotieren dec edx // dec(edx) jnz @Loop // wenn edx <> 0 --> springe zu Loop @Ende: end;
Delphi-Quellcode:
habt ihr vielleicht einen noch schnelleren Ansatz ohne LookUpTable?
function BitRev(inBit{eax}: Cardinal; BitCount{edx}: integer): Cardinal;
asm mov ecx, edx lea edx, [eax * 2] shr eax, 1 and edx, $AAAAAAAA and eax, $55555555 or eax, edx lea edx, [eax * 4] shr eax, 2 and edx, $CCCCCCCC and eax, $33333333 or eax, edx lea edx, [eax * 8] shl edx, 1 shr eax, 4 and edx, $F0F0F0F0 and eax, $0F0F0F0F or eax, edx bswap eax rol eax, cl end; der Mischka |
AW: Bit Reverse Algorithmus
Warum nicht Lookup? Das scheint eigentlich der Stand der Technik zu sein, wenn es schnell sei muss. Zumal es ohne (für manche Menschen) unverständlichen Assemblercode auskommt.
Sherlock |
AW: Bit Reverse Algorithmus
Zitat:
Bei großen Datenmengen wird immer mehr die Speicherbandbreite der limitierende Faktor. der Mischka |
AW: Bit Reverse Algorithmus
Zitat:
Ein Lookup ist quasi nur ein mov-Befehl. Gefühlt (ich habs nicht getestet) sollte das unabhängig vom Speicher am schnellsten sein. Allein weil es deutlich weniger Taktzyklen benötigt als eine Umrechnung. |
AW: Bit Reverse Algorithmus
Eine wie auch immer geartete Assemblerlösung (mit einer Ausnahme) ist immer langsamer als eine simple LUT. Welche Ausnahme? Eine Assemblerimplementierung einer LUT. ;)
Zu Deinem Problem der variablen Länge: Ich gehe davon aus, daß sich die Bitfolge immer glatt in Nibbles aufteilen läßt, dann brauchst Du eine kleine Tabelle mit 16 Einträgen, gegen Die Du die Nibbles laufen läßt, und vertauscht dann deren Reihenfolge. Das sollte zwei bis drei Kernkriterien der Softwareentwicklung erfüllen: Einfach, Lesbar, Wartbar. Wenn Du immer glatt in Bytes aufteilen kannst, dann machst Du eine größere Tabelle (256 Einträge) und mußt weniger Folgenteile vertauschen. Diskussion dazu zB hier: https://stackoverflow.com/questions/...byte-in-delphi insbesondere in der akzeptierten Lösung von seiner Delphihaftigkeit David Heffernan. Sherlock |
AW: Bit Reverse Algorithmus
Zitat:
selbst eine Assembler LUT version wäre nicht so klein ... Pseudo-Asm-Code
Code:
// eax = Value
// edx = BitCount movzx ecx, al mov cl, [LUT + ebx] movzx ebx, ah mov ch, [LUT + ebx] shr eax, 16 movzx ebx, al mov bl, [LUT + ebx] shr eax, 8 mov bh, [LUT + eax] or ebx, ecx bswap ebx mov ecx, edx rol ebx, cl mov eax, ebx |
AW: Bit Reverse Algorithmus
Ich fand da interesasnt:
Zitat:
|
AW: Bit Reverse Algorithmus
Zitat:
Deshalb suche ich Anregungen für eine schnelle Umsetzung ohne LUT. der Mischka |
AW: Bit Reverse Algorithmus
Ich vermute mal deine Lösung entspricht dem:
https://stackoverflow.com/questions/...o-lsb-msb-in-c Du könntest ja auch mal den Algorithmus in Delphi schreiben und schauen was er im Assembler daraus macht. Ichkönnte mir vorstellen das Delphi sowas ganz gut optimieren kann. Rollo |
AW: Bit Reverse Algorithmus
Was ist denn das Maximum für BitCount 32? Eine Idee wäre noch 32 Varianten für jedes Bitcount der Methode zu machen und über eine Tabelle mit Index Bitcount anzuspringen. Intern kannst du dann die Loop ausrollen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz