Peter B. schrieb:> Wie kann man bitte ein Byte : 11000001 am schnellsten umsetzen> nach : 10000011 mit Schieben, AND , Or usw?
Mit einer Tabelle. Oder Hardcore Inline Assembler.
Peter B. schrieb:> Wie kann man bitte ein Byte : 11000001 am schnellsten umsetzen> nach : 10000011 mit Schieben, AND , Or usw?
mit dem passenden Maschinenbefehl" 'reverse (Address-) bit order'
DSP haben einen solchen Befehl, weil er den Butterfly-FFT Algo immens
beschleunigt. In den PC-x86 addresssatz könnte man sowas auch in den
MME-Teil o.ä. finden.
Danke für die Info.
Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.
Wir fliegen zum Mond und schreiben Bücher über dieses Bit im Byte
tauschen.... hm
Gruss
Peter B. schrieb:> Wir fliegen zum Mond und schreiben Bücher über dieses Bit im Byte> tauschen.... hm
Na, desewegen konnten wir ja erst zum Mondfliegen!
Peter B. schrieb:> Wir fliegen zum Mond und schreiben Bücher über dieses Bit im Byte> tauschen.... hm
Eine Frage eindeutig zu stellen kann es mitunter ersparen, bücherweise
Antworten zu lesen.
Peter B. schrieb:> Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.
Du hast nach der schnellsten Methode gefragt und das ist zweifelsohne
eine Tabelle, wenn man man mal von festverdrahteter Logik absieht. Das
ist kein Krampf, sondern straight forward - direkter geht es nicht.
Wolfgang schrieb:> direkter geht es nicht
Doch. Bitreverse geht direkter und schneller - wenn als Befehl vorhanden
und genau das gewünscht ist. Tabelle hat demgegenüber den Vorteil, trotz
vage formulierter Frage auf jedem Prozessor für jede Permutation
geeignet zu sein. Daher ist die Tabelle die schnellere Antwort auf die
Frage, aber nicht unbedingt das zur Laufzeit schnellere Verfahren.
(prx) A. K. schrieb:> Wolfgang schrieb:>> direkter geht es nicht>> Doch. Bitreverse geht direkter und schneller - wenn als Befehl vorhanden> und genau das gewünscht ist.
Das muss nicht sein. Es gibt auch Befehle, die sind schneller wenn man
die per hand bastelt statt dem fertigen Befehl, bei x86 war es beim loop
befehl so, afaik.
Jens B. schrieb:> Das muss nicht sein. Es gibt auch Befehle, die sind schneller wenn man> die per hand bastelt statt dem fertigen Befehl, bei x86 war es beim loop> befehl so, afaik.
Im Prinzip richtig, aber kennst du einen Prozessor mit
Bitreverse-Befehl, der sich dafür dementsprechend viel Zeit lässt?
Beim LOOP war es auch schon so, dass der vorsätzlich ausgebremst
wurde, damit ein herzallerliebstes Betriebssystem überhaupt bootete. ;-)
(prx) A. K. schrieb:> Wolfgang schrieb:>> direkter geht es nicht>> Doch. Bitreverse geht direkter und schneller - wenn als Befehl vorhanden> und genau das gewünscht ist.
Bei divesren ARM's könnte RBIT das gesuchte sein:
https://developer.arm.com/documentation/dui0802/a/A32-and-T32-Instructions/REV--REV16--REVSH--and-RBIT
Oder man hat programmierbare Logik und bastelst sich diese Instruction
aus ein bißchen routing ressourcen und FF.
Und natürlich stellt sich die Frage, wie man das transponierte
weiterverwenden will, alls addresspointer braucht man es nicht extra
drehen sondern könnte es beim TMS320 direkt zu bit reversal addressing
verwenden.
Aber das wurde, wie gesagt, hier schon mal durchgekaut, mehr als einmal.
> Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.
Das ist kein Krampf , das ist ganz simples bitschubsen. Wenn das zuviel
für Deine Computerfähigkeiten ist, könntest du dir ja was weniger
Anspruchsvolles als Freizeitbeschäftigung aussuchen.
Peter B. schrieb:> Wie kann man bitte ein Byte : 11000001 am schnellsten umsetzen> nach : 10000011 mit Schieben, AND , Or usw?
Welche CPU?
Früher wurden noch die Bios-Befehle benutzt, und da hätte man wohl AND
und/oder je nach Vorfall OR genommen - aber der Rotationsbefehl einmal
bzw. zweimal (über das Carry-Flag) nach links geht natürlich auch, nur
war der früher etwas langsam.
Dafür isser aber für die Ausgabe der Bits sehr praktisch.
https://www.i8086.de/asm/8086-88-asm-rcl.htmlhttps://www.davespace.co.uk/arm/introduction-to-arm/barrel-shifter.html
Patrick L. schrieb:> wenn du 2 Ports frei hast, diese extern Gespiegelt verdrahten und dann> geht das sehr fix über Port Out und Port in.
Port IO ist selten fix.
Peter B. schrieb:> Danke für die Info.>> Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.>> Wir fliegen zum Mond und schreiben Bücher über dieses Bit im Byte> tauschen.... hm
Das sind Fingerübungen. Wenn sowas öfter gebraucht würde, würde es dafür
ein Modul geben. Ich hätte es einmal gebraucht. Der Prozessor konnte es
sogar (mirror), aber es lohnte nicht den Aufwand, da einen
Assembler-Befehl einzufügen.
Normalerweise bin ich ja kein fan von bitfields, aber bits reversen ist
lästig. Da würde ich die dann doch nehmen, und das Optimieren dem
Compiler überlassen:
https://godbolt.org/z/dP6T837nq
🐧 DPA 🐧 schrieb:> Wow, tatsächlich. Es nutzt rbit:> https://godbolt.org/z/c4ozsvP3otest:> // @test> rbit w8, w0> lsr w0, w8, #24> ret>> Zwar nur bei recht aktueller clang Version, aber trotzdem. Da sieht man> mal wieder, heute noch selber Assembler schreiben bringts nicht mehr.
Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart
man sich die 30 zeilen C-Code und die Überprüfung ob der C-Compiler das
C-Construct erkennt und wie gewünscht in die drei Assembler Zeilen
umsetzt. Und er das immer tut und nicht abhängig wegen irgendwelchen
genutzten Compilerschaltern, Mandphasen etc. pp. .
Zum Kellnern sagt man ja auch "Bringens mir bitte ein halbes Hefeweiße"
und setzt nicht zu einem verquasten Vortrag über seine aktuelle
Befindlichkeit bezüglich Kaltgetränke an, um ne Viertelstunde später den
Kellner wieder zurückzuschicken, weil er ein veganes Alkoholfreies
gebracht hat.
Falls man seine Ansprache überhaupt an den richtigen Kellner gerichtet
hat und nicht an einen Touristen, der sich aus Unkenntnis der
Alltagsgebräuche wie ein Lokalkellner gekleidet hat.
Assembler gehört zum Handwerkszeug schrieb:> Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart> man sich die 30 zeilen C-Code und die Überprüfung ob der C-Compiler das> C-Construct erkennt und wie gewünscht in die drei Assembler Zeilen> umsetzt. Und er das immer tut und nicht abhängig wegen irgendwelchen> genutzten Compilerschaltern, Mandphasen etc. pp. .
Da bin ich ganz deiner Meinung. ;-)
Assembler gehört zum Handwerkszeug schrieb:> Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart> man sich die 30 zeilen C-Code
Spätestens beim Port auf einen anderen µC bist Du aufgeschmissen. Der
C-Code jedoch funktioniert mit allen µCs. Und dort wird er möglichst
optimal übersetzt.
Als C-Programmierer machst Du 30 Ports mühelos mit, als
Assembler-Programmierer musst du einfach aufgeben.
Assembler gehört zum Handwerkszeug schrieb:> Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart> man sich die 30 zeilen C-Code und die Überprüfung ob der C-Compiler das> C-Construct erkennt und wie gewünscht in die drei Assembler Zeilen> umsetzt. Und er das immer tut und nicht abhängig wegen irgendwelchen> genutzten Compilerschaltern, Mandphasen etc. pp. .
1. Der C-Code funktioniert auf so ziemlich allen Platformen. Die meisten
davon haben keine rbit Instruktion.
2. Ich wusste gar nicht, dass ARMv8 diese Instruktion besitzt. Bis ich
mir alle Instruktionen nochmal durchgesehen habe, um mir zu überlegen,
wie ich das am besten mache, habe ich den C Code schon längstens
eingetippt. Der C Code ist auch absolut trivial und einfach zu
verstehen. Da sieht man sofort, was er macht. Das man etwas mehr
Eintippt ist doch egal.
3. Ich muss nicht nachschauen, wie gut der Compiler das optimiert. Dass
kann mir erstmal egal sein. Wenn etwas zu langsam ist, nehme ich den
Profiler raus. Und wenn der anzeigt, dass diese Funktion am meisten zeit
verschwendet, erst dann lohnt es sich, überhaupt über das Optimieren
nachzugenken.
4. Der Compiler kann das sehr wohl inlinen. Das hat er bei der Funktion
test() auch gemacht. Aber auch ohne das static inline kann und tut der
Compiler inlinen, wenn sinvoll.
5. Punkto Stabilität, ok, der Code könnte sich ändern. Ich habe aber
noch nie gesehen, dass er mit neueren Compilern verschlechtern würde.
Wenn man das wirklich unbedingt verhindern muss / will, warum auch
immer, gibt es mehrere Möglichkeiten. Entweder, man legt einfach fest,
welchen Compiler man verwenden soll (also Version, Build, usw.). Oder
man packt sich die guten Assembler Versionen irgendwo hin, und lässt die
die C Versionen ersetzen (beim build), sofern man die für die Plattform
hat. (Aber dann auch immer reine C Builds testen, damit man die
Originale nicht versehentlich mal löscht, und später wieder suchen
muss).
So oder so, kein Grund sich selbst anstrengen & mit ASM abmühen zu
müssen.
Frank M. schrieb:> Als C-Programmierer machst Du 30 Ports mühelos mit,
Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen ob er
wirklich die gewollte optimale Assembler-Variante generiert hat.
> Assembler-Programmierer musst du einfach aufgeben.
Also Programmierer steht man über die infantilen Streiteren ob
assembler oder C der 'Heilige Scheiß' sei und verlässt sich nicht auf
die maschinelle (Un-)Intelligenz) eines Compilers.
Und auch als Programmierer der den befehlssatz und CPU-Architekturen
beherrscht, ist man nicht gezwungen alles in Assembler-Mnemonics zu
schreiben, sondern kann ganz profesionell, inline Assembler verwenden,
wo er gegenüber Compiler-hHrsteller spezifischen C-Konstrukten
effizienter und schneller ist.
Man will ja schliesslich 'Computer beherschen' und nicht als
'Syntax-idiotischer' C-Fachtrottel-Programmierschwein enden.
Assembler gehört zum Handwerkszeug schrieb:> Frank M. schrieb:>> Als C-Programmierer machst Du 30 Ports mühelos mit,> Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen ob er> wirklich die gewollte optimale Assembler-Variante generiert hat.
1. Warum musst du das machen?
2. Kennst du immer die optimale Lösung?
Assembler gehört zum Handwerkszeug schrieb:> sondern kann ganz profesionell, inline Assembler verwenden,> wo er gegenüber Compiler-hHrsteller spezifischen C-Konstrukten> effizienter und schneller ist.
Wie würdest du die rbit Variante vom Compiler effizienter gestalten?
Assembler gehört zum Handwerkszeug schrieb:> Man will ja schliesslich 'Computer beherschen' und nicht als> 'Syntax-idiotischer' C-Fachtrottel-Programmierschwein enden.
Darunter verstehe ich was anderes. Dass der Computer macht, was ich
will. Wie das passiert, ist mir ziemlich egal, Hauptsache niemand kann
mir vorschreiben, was ich machen kann, oder auch nicht. Daher ist mir da
viel wichtiger, das mein Computer nicht ein abgeschottetes Smartphone
oder was in die Richtung ist, und ich möglichst viel DRM zeug vermeide,
als das alles in ASM geschrieben ist, bei dem keiner mehr durch blickt.
🐧 DPA 🐧 schrieb:> Normalerweise bin ich ja kein fan von bitfields, aber> bits reversen ist lästig. Da würde ich die dann doch> nehmen, und das Optimieren dem Compiler überlassen:
Und Du glaubst, das wird schneller als
Assembler gehört zum Handwerkszeug schrieb:> Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen
Ich muss gar nix prüfen, der C-Code läuft einfach - auf dem einen µC
performanter (dank rbit), auf dem anderen mangels passender Instruktion
weniger performant. Aber was soll's?
Der Assembler-Programmierer muss den Code für jeden µC neu schreiben
oder er verrottet auf seinem ATTiny. Bestes Beispiel: Moby, der kann
auch nix anderes als ATTinys programmieren.
Assembler gehört zum Handwerkszeug schrieb:> Also Programmierer steht man über die infantilen> Streiteren ob assembler oder C der 'Heilige Scheiß' sei
Man folgert leicht: Du bist kein Programmierer.
> Und auch als Programmierer der den befehlssatz und> CPU-Architekturen beherrscht,
Da hätte ich ja viel zu tun.
Wenn ich ein Anwendungsprogramm entwickle, will ich dem
Nutzer vor allem ein Werkzeug zur Verfügung stellen, das
sein Problem löst. Da ich nicht wissen kann, welche CPU der
Anwender benutzt, beschränke ich mich im wohlverstandenen
Eigeninteresse auf die Auswahl und die Optimierung von
Algorithmen, die mit üblichen Architekturen möglichst gut
harmonieren. Alles, was darüber ist, ist vom Übel.
> ist man nicht gezwungen alles in Assembler-Mnemonics zu> schreiben, sondern kann ganz profesionell, inline Assembler> verwenden, wo er gegenüber Compiler-hHrsteller spezifischen> C-Konstrukten effizienter und schneller ist.
Frei nach C.F.Gauss: "Mangelnde computertechnische Bildung
zeigt sich am deutlichsten in äußerster Schärfe bei der
Mikro-Optimierung."
> Man will ja schliesslich 'Computer beherschen' und nicht als> 'Syntax-idiotischer' C-Fachtrottel-Programmierschwein enden.
???
Ich will vor allem gute Programme schreiben.
Das ist etwas anderes als "Programme schreiben, die auf meinem
aktuellen Computer schnell laufen".
Frank M. schrieb:> Assembler gehört zum Handwerkszeug schrieb:>> Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen>> Ich muss gar nix prüfen, der C-Code läuft einfach - auf dem> einen µC performanter (dank rbit), auf dem anderen mangels> passender Instruktion weniger performant. Aber was soll's?
Naja, die Frage bleibt: Wie drücke ich das in C so aus, dass
der Compiler bei Verfügbarkeit "rbit" verwendet und andernfall
z.B. die von mir gepostete Formel?
> Der Assembler-Programmierer muss den Code für jeden µC neu> schreiben
Dürfen nur Assemblerprogrammierer Assembleranweisungen
verwenden?
rotation googeln schrieb:> rotation googeln schrieb:>>> sieht nach "rotation" aus.>> nee ;-)
Doch. Sieht so aus. Er hat halt ein blödes Beispiel geeählt.
Egon D. schrieb:> 🐧 DPA 🐧 schrieb:>>> Normalerweise bin ich ja kein fan von bitfields, aber>> bits reversen ist lästig. Da würde ich die dann doch>> nehmen, und das Optimieren dem Compiler überlassen:>> Und Du glaubst, das wird schneller als> b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
Ok, multiplizieren ist etwas schneller bei x86:
https://godbolt.org/z/a1Ph37ffW
Aber auch wenn ich selbst Assembler geschrieben hätte wäre ich nicht auf
die Idee gekommen.
Man könnte jetzt im build script ein benchmark einbauen, um eine
Variante auszuwählen, oder alternativ je nach Architekturen in den build
scripts hinterlegen, welche Variante besser ist. Aber das ist dann doch
Overkill.
🐧 DPA 🐧 schrieb:> Aber auch wenn ich selbst Assembler geschrieben hätte> wäre ich nicht auf die Idee gekommen.
Bin ich auch nicht. Das stammt von den "bit twiddling hacks".
> Man könnte jetzt im build script ein benchmark einbauen,> um eine Variante auszuwählen, oder alternativ je nach> Architekturen in den build scripts hinterlegen, welche> Variante besser ist. Aber das ist dann doch Overkill.
Warum eigentlich? Solche Grundoperationen können schon in
der bestmöglichen Variante zur Verfügung stehen, finde ich.
Man will ja das Rad nicht jedesmal neu erfinden...
(prx) A. K. schrieb:> Haben deine Bytes nur 6 Bits? ;-)
Der Codeabschnitt für die 6 Bits schaut halt so schön regelmäßig und
geordnet aus...
Konnte ja nicht ahnen, dass hier jemand nachzählt :)
🐧 DPA 🐧 schrieb:> Aber auch wenn ich selbst Assembler geschrieben hätte wäre ich nicht auf> die Idee gekommen.>> Man könnte jetzt im build script ein benchmark einbauen, ..
Man könnte beim Intel auch mal schauen, wie weit man hier mit LEA kommt.
Oder mit den CPU-Erweiterungen. Die sind zwar oft mit Speicheraufruf
verbunden, wie auch die FPU - aber man kann auch Sachen machen, die der
C oder ähnlich Compiler vermutlich eh nicht kann. Aber LEA geht schon
mit Compiler. Ist aber auch alles ein wenig Übungsache.
Überhaupt ist man, wenn man so ein Forum mit Top-Leuten kennt, wenn es
mal drauf ankommt, gar nicht so allein mit Fragen zum Code.
Vor allem auch deswegen, weil Assembler nur eine Möglichkeit ist, ein
Programm schneller oder kleiner zu machen. Der wahre Hintergrund für
bessere Programme ist aber Know How und Hingabe, nicht irgendeine
Programmierhilfe.
Früher war der Gedanke verbreitet, der Computer macht die Musik. Das ist
aber nur ein Irrglaube, eine Täuschung.
Egon D. schrieb:>> Man könnte jetzt im build script ein benchmark einbauen,>> um eine Variante auszuwählen, oder alternativ je nach>> Architekturen in den build scripts hinterlegen, welche>> Variante besser ist. Aber das ist dann doch Overkill.>> Warum eigentlich? Solche Grundoperationen können schon in> der bestmöglichen Variante zur Verfügung stehen, finde ich.> Man will ja das Rad nicht jedesmal neu erfinden...
Die diversen build tools (make, cmake, automake, meson) haben das noch
nicht fertig eingebaut. Es gibt Wege, das dort selbst einzubauen, aber
das ist aufwändig, und die meisten Entwickler wollen sich nicht all zu
sehr mit den Buid Tools herumschlagen.
Ich habe als Beispiel in make mal etwas herum experimentiert, wie so
etwas aussehen könnte:
https://github.com/Daniel-Abrecht/test-variouse-make-stuff
Es ist bei weitem nicht perfekt, einiges fehlt noch, aber gibt eine
grobe Idee, was man so alles machen könnte.
Mal noch eine Frage um da nochmals Nachzuhaken.
Welchen CPU verwendest du überhabt?
Ich habe grad heute in einer Software genau das Bit-spiegeln
gebraucht(war für eine Tastatur-abfrage).
Glücklicherweise habe ich einen µP Verwendet der ein "LEA" Coprozessor
onboard hat, der ist speziell für Filter,DSP, FFT Funktionen.
Da gibt es doch tatsächlich ein befehl für genau dies mit 8/16 oder 32
Bit macht.
1
msp_cmplx_bitrev_q15 Complex bit-reversal function
2
msp_cmplx_bitrev_iq31 Complex bit-reversal function
Peter B. schrieb:> Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.
Das ist im Grunde kein Problem.
Also für die meisten nicht.
Für einige offenbar schon.
Computer-Spezialist schrieb:> Also für die meisten nicht.> Für einige offenbar schon.
Problem ist es nicht, aber wenn ich dass als Programm schreibe erkennt
der IAR C Kompiler dies nicht selbstständig, dass man ja den LEA-Core
dazu "missbrauchen" kann und "Bastelt" eine Ruine die sage und schreibe
65 Cycles braucht, das hat mich genervt und an den Thread hier gedacht.
Habe dann einfach die Daten ans richtige LEA Register übergeben und kann
das Reversebyte dann abholen. braucht noch 6 Cyclen für 16 Bit!